主要学习计算机图形学的一些基本知识,参考 Learning Modern 3D Graphics Programming 一书.

GitHub 地址 https://github.com/paroj/gltut

附:

vscode 正则替换不规则语句:

_\s*([\u4e00-\u9fff]+)\s*([。]?)_
<u>$1</u>$2

Q&A

介绍下光栅化过程

让我为您详细介绍光栅化过程及其关键步骤:

  1. 图元装配 (Primitive Assembly)
  • 将顶点着色器输出的顶点数据组装成基本图元 (三角形、线段、点等)
  • 对于三角形网格,每三个顶点组成一个三角形图元
  1. 裁剪 (Clipping)
  • 判断图元是否在可视区域内
  • 如果部分可见,将图元裁剪到视锥体内
  • 完全不可见的图元被丢弃,提高性能
  1. 透视除法 (Perspective Division)
  • 将裁剪空间坐标转换为规范化设备坐标 (NDC)
  • 通过将 x、y、z 分量除以 w 分量实现
  • 将 3D 坐标映射到 2D 平面
  1. 屏幕映射 (Screen Mapping)
  • 将 NDC 坐标转换为屏幕空间坐标
  • 考虑视口 (Viewport) 的大小和位置
  • 确定像素的实际位置
  1. 三角形遍历 (Triangle Traversal)
  • 确定三角形覆盖的像素范围
  • 使用各种算法 (如扫描线算法) 遍历像素
  • 处理三角形边缘的反走样
  1. 像素着色 (Pixel Shading)
  • 对每个像素执行片段着色器
  • 计算最终的颜色值
  • 应用纹理、光照等效果
  1. 深度测试 (Depth Testing)
  • 比较当前片段与已存储片段的深度值
  • 决定是否更新颜色缓冲区
  • 处理透明物体的渲染顺序
  1. 颜色混合 (Color Blending)
  • 将新的片段颜色与已存在的颜色混合
  • 处理透明度
  • 应用混合模式 (如相加、相乘等)

重要的优化技术:

  1. Early-Z: 在像素着色之前进行深度测试,避免不必要的着色计算
  2. Tile-based rendering: 将屏幕分成小块进行渲染,提高缓存效率
  3. Hierarchical-Z: 使用层次化的深度缓冲进行快速剔除

为什么渲染可视化过程叫光栅化,光栅有什么形象方面的含义么

光栅化(Rasterization)这个术语源于电视显示技术中的 ” 光栅扫描 “(Raster Scan)。让我解释一下它的形象含义:

  1. 历史渊源:
  • 早期 CRT(阴极射线管)电视显示器中,电子束会从左到右、从上到下按行扫描屏幕
  • 这种扫描方式形成了一种类似 ” 耙子 ” 或 ” 梳子 ” 的图案
  • “Raster” 在拉丁语中就有 ” 耙子 ” 的意思
  1. 形象类比: 想象一个农民用耙子耕地:
  • 耙子齿形成平行的线
  • 从一端到另一端系统地耕作
  • 一行行地覆盖整个区域 这和光栅化过程非常相似:
  • 显示器按行扫描
  • 像素按特定顺序填充
  • 最终覆盖整个屏幕
  1. 现代含义: 现在光栅化主要指:
  • 将矢量图形(如线条、多边形)转换成像素点阵的过程
  • 确定哪些像素被图形覆盖
  • 为这些像素计算颜色值

这种按像素填充的方式,和早期电视的扫描线原理有着直接的联系,因此保留了 ” 光栅化 ” 这个名字。

片段和像素是否是一个概念

片段 (Fragment) 和像素 (Pixel) 虽然关系密切但不是完全相同的概念。让我解释它们的区别:

片段 (Fragment):

  1. 定义
  • 是渲染管线中的一个中间概念
  • 包含了可能会成为像素的所有信息 (颜色、深度、纹理坐标等)
  • 是光栅化阶段产生的
  1. 特点
  • 一个像素位置可能对应多个片段
  • 不是所有片段最终都会变成像素
  • 包含更多信息 (深度值、模板值等)

像素 (Pixel):

  1. 定义
  • 是最终显示在屏幕上的实际显示单元
  • 只包含最终的颜色信息
  • 是渲染管线的最终输出结果

举个例子来说明区别: 想象你在渲染一个半透明的玻璃物体:

  1. 光栅化后,同一个屏幕位置会产生多个片段 (玻璃的前面和后面)
  2. 这些片段经过深度测试、混合等操作
  3. 最终只有一个颜色值会被写入到这个位置的像素中

所以片段可以理解为 ” 像素的候选者 “,需要经过一系列测试和处理才可能成为最终的像素。