Skip to content

光栅化管线

光栅化管线由多个有序阶段组成,每个阶段专注于特定的处理任务,共同协作完成渲染。管线运行于 GPU,充分利用其并行计算能力,达到实时渲染的性能要求(通常 30-60 帧每秒)。光栅化管线的设计兼顾了速度与质量,适用于游戏、虚拟现实、实时可视化等场景。

光栅化管线与光线追踪管线不同,前者基于几何投影和像素填充,快速生成近似光照效果;后者模拟真实光路,追求物理真实感,但计算成本较高。光栅化管线的优势在于硬件优化和实时性,使其成为现代图形渲染的基石。

主要流程

光栅化管线由以下主要阶段组成,分为 CPU 端的应用程序阶段和 GPU 端的渲染阶段。每个阶段功能明确,协同完成从几何源数据到图形像素的转换。

应用程序阶段

  • 应用程序阶段(Application Stage)运行于 CPU,由开发者控制,负责准备渲染所需的数据(模型、图像、材质等)和逻辑(shader 着色器)。
  • 任务:
    • 场景管理:组织三维场景中的物体(模型、相机、光源)。
    • 数据准备:生成顶点数据(位置、法向量、纹理坐标)、索引缓冲区、纹理、变换矩阵(模型、视图、投影)。
    • 动画与物理:计算物体运动、骨骼动画、碰撞检测等。
    • 剔除优化:执行视锥剔除(Frustum Culling)、遮挡剔除(Occlusion Culling),减少无效物体提交。
    • 绘制命令:通过 API(如 glDrawArrays)提交渲染指令。
  • 优化点:
    • 批量提交数据,减少 CPU-GPU 通信。
    • 使用顶点缓存(Vertex Buffer Objects, VBO)高效传输几何。

顶点着色

  • 顶点着色(Vertex Shading)是 GPU 上运行的可编程阶段,处理每个顶点的几何变换和属性计算。注意,该顶点着色命名极具误导性,其更贴切的命令应当是投影变换
  • 任务:
    • 坐标变换:将模型的顶点从模型空间依次变换到世界空间、观察空间(视图矩阵)、裁剪空间(投影矩阵)。
    • 属性计算:处理法向量(用于光照)、纹理坐标、顶点颜色等。
    • 输出:裁剪空间坐标(gl_Position)和其他属性,传递给后续阶段。
  • 优化点:使用统一变量(Uniforms)传递矩阵,减少重复计算。

图元装配

  • 图元组装与裁剪(Primitive Assembly & Clipping)将顶点组织为图元(如三角形、线段、点),并进行裁剪优化。
  • 任务:
    • 图元组装:根据绘制命令(如 GL_TRIANGLES)和索引,将顶点连接为三角形。
    • 背面剔除:根据顶点顺序(逆时针 CCW 为正面,顺时针 CW 为反面)移除不可见三角形(glEnable(GL_CULL_FACE))。
    • 视锥裁剪:剔除位于视锥体外的图元,裁剪部分可见图元。
  • 优化点:提前剔除减少光栅化负担。

光栅化

  • 光栅化(Rasterization)将连续的图元转换为离散的像素片段(Fragments)。
  • 任务:
    • 扫描转换:确定三角形覆盖的像素,使用扫描线算法。
    • 属性插值:插值顶点属性(如颜色、法线、纹理坐标),生成每个片段的数据。
    • 透视校正:对纹理坐标等属性进行透视校正,避免失真。
  • 优化点:使用多级纹理(Mipmaps)优化纹理采样。

片段着色

  • 片段着色(Fragment Shading)为每个片段(即像素点)计算最终颜色,决定像素外观。该步骤利用光照模型,模拟计算场景中的灯光打到模型表面时,在相机的视角应当看见的颜色数据。是整个图形渲染的核心步骤。
  • 任务:
    • 光照模型:实现环境光、漫反射(Lambert)、镜面反射(Phong)等光源的模拟计算。
    • 纹理采样:从纹理中获取颜色或法线(法线贴图)。
    • 高级效果:阴影贴图、环境光遮蔽(SSAO)、基于物理的渲染(PBR)。
  • 优化点:延迟渲染(Deferred Shading)减少光照计算。

测试与混合

  • 测试与混合(Testing & Blending)决定片段是否写入帧缓冲区,以及如何与现有像素合成。
  • 任务:
    • 深度测试:比较片段深度(glEnable(GL_DEPTH_TEST)),剔除被遮挡的片段。
    • 模板测试:用于特殊效果(如轮廓、镜像)。
    • 混合:处理透明效果(glBlendFunc),如玻璃、烟雾。
    • 抗锯齿:如多重采样抗锯齿(MSAA),平滑边缘。
  • 优化点:早期深度测试(Early-Z)减少片段着色开销。

输出与显示

  • 输出与显示(Framebuffer Output)将帧缓冲区的像素数据显示到屏幕。
  • 任务:
    • 双缓冲交换(glfwSwapBuffers),避免闪烁。
    • 输出到渲染目标(Render Target),用于后处理或离屏渲染。