主要学习计算机图形学的一些基本知识,参考 Learning Modern 3D Graphics Programming 一书.
GitHub 地址 https://github.com/paroj/gltut
附:
vscode 正则替换不规则语句:
_\s*([\u4e00-\u9fff]+)\s*([。]?)_
<u>$1</u>$2
Q&A
介绍下光栅化过程
让我为您详细介绍光栅化过程及其关键步骤:
- 图元装配 (Primitive Assembly)
- 将顶点着色器输出的顶点数据组装成基本图元 (三角形、线段、点等)
- 对于三角形网格,每三个顶点组成一个三角形图元
- 裁剪 (Clipping)
- 判断图元是否在可视区域内
- 如果部分可见,将图元裁剪到视锥体内
- 完全不可见的图元被丢弃,提高性能
- 透视除法 (Perspective Division)
- 将裁剪空间坐标转换为规范化设备坐标 (NDC)
- 通过将 x、y、z 分量除以 w 分量实现
- 将 3D 坐标映射到 2D 平面
- 屏幕映射 (Screen Mapping)
- 将 NDC 坐标转换为屏幕空间坐标
- 考虑视口 (Viewport) 的大小和位置
- 确定像素的实际位置
- 三角形遍历 (Triangle Traversal)
- 确定三角形覆盖的像素范围
- 使用各种算法 (如扫描线算法) 遍历像素
- 处理三角形边缘的反走样
- 像素着色 (Pixel Shading)
- 对每个像素执行片段着色器
- 计算最终的颜色值
- 应用纹理、光照等效果
- 深度测试 (Depth Testing)
- 比较当前片段与已存储片段的深度值
- 决定是否更新颜色缓冲区
- 处理透明物体的渲染顺序
- 颜色混合 (Color Blending)
- 将新的片段颜色与已存在的颜色混合
- 处理透明度
- 应用混合模式 (如相加、相乘等)
重要的优化技术:
- Early-Z: 在像素着色之前进行深度测试,避免不必要的着色计算
- Tile-based rendering: 将屏幕分成小块进行渲染,提高缓存效率
- Hierarchical-Z: 使用层次化的深度缓冲进行快速剔除
为什么渲染可视化过程叫光栅化,光栅有什么形象方面的含义么
光栅化(Rasterization)这个术语源于电视显示技术中的 ” 光栅扫描 “(Raster Scan)。让我解释一下它的形象含义:
- 历史渊源:
- 早期 CRT(阴极射线管)电视显示器中,电子束会从左到右、从上到下按行扫描屏幕
- 这种扫描方式形成了一种类似 ” 耙子 ” 或 ” 梳子 ” 的图案
- “Raster” 在拉丁语中就有 ” 耙子 ” 的意思
- 形象类比: 想象一个农民用耙子耕地:
- 耙子齿形成平行的线
- 从一端到另一端系统地耕作
- 一行行地覆盖整个区域 这和光栅化过程非常相似:
- 显示器按行扫描
- 像素按特定顺序填充
- 最终覆盖整个屏幕
- 现代含义: 现在光栅化主要指:
- 将矢量图形(如线条、多边形)转换成像素点阵的过程
- 确定哪些像素被图形覆盖
- 为这些像素计算颜色值
这种按像素填充的方式,和早期电视的扫描线原理有着直接的联系,因此保留了 ” 光栅化 ” 这个名字。
片段和像素是否是一个概念
片段 (Fragment) 和像素 (Pixel) 虽然关系密切但不是完全相同的概念。让我解释它们的区别:
片段 (Fragment):
- 定义
- 是渲染管线中的一个中间概念
- 包含了可能会成为像素的所有信息 (颜色、深度、纹理坐标等)
- 是光栅化阶段产生的
- 特点
- 一个像素位置可能对应多个片段
- 不是所有片段最终都会变成像素
- 包含更多信息 (深度值、模板值等)
像素 (Pixel):
- 定义
- 是最终显示在屏幕上的实际显示单元
- 只包含最终的颜色信息
- 是渲染管线的最终输出结果
举个例子来说明区别: 想象你在渲染一个半透明的玻璃物体:
- 光栅化后,同一个屏幕位置会产生多个片段 (玻璃的前面和后面)
- 这些片段经过深度测试、混合等操作
- 最终只有一个颜色值会被写入到这个位置的像素中
所以片段可以理解为 ” 像素的候选者 “,需要经过一系列测试和处理才可能成为最终的像素。