渲染管线

GPU 渲染的完整流程——顶点着色器 → 光栅化 → 片段着色器 → 后处理。

概念

渲染管线 (Rendering Pipeline) 是将 3D 场景数据 (顶点、纹理、光照) 转换为 2D 屏幕像素的完整流程。现代 GPU 的管线是高度并行的——每个顶点和每个像素 (片段) 都由独立的着色器程序处理。理解渲染管线相当于理解”如何高效利用 GPU 的大规模并行能力”。

核心组件

组件职责硬件实现
顶点着色器 (Vertex Shader)将模型空间的顶点变换到裁剪空间每个顶点并行执行
曲面细分 (Tessellation)动态细分曲面增加几何细节可选, 硬件曲面细分单元
几何着色器 (Geometry Shader)生成/销毁图元 (点、线、三角形)可选
光栅化 (Rasterizer)将图元转化为屏幕像素 (片段)固定功能硬件
片段着色器 (Fragment Shader)计算每个片段的颜色每个片段并行执行
深度/模板测试 (Depth/Stencil)隐藏面消除 (Z-buffer)固定功能硬件
后处理 (Post-Process)全屏特效: bloom, HDR tone mapping, SSAO片段着色器实现

渲染管线全流程

mermaid
graph TD
    VBO["顶点缓冲区 (VBO)<br/>positions, normals, UVs"] --> VS["顶点着色器<br/>MVP 变换: model→world→view→clip"]
    VS --> TESS["曲面细分<br/>动态几何细节"]
    TESS --> GS["几何着色器<br/>图元操作"]
    GS --> CLIP["裁剪 + 透视除法<br/>clip → NDC → window"]
    CLIP --> RAST["光栅化<br/>三角形遍历, 生成片段"]
    RAST --> FS["片段着色器<br/>纹理采样 + 光照计算"]
    FS --> DS["深度/模板测试<br/>Z-buffer 隐藏面消除"]
    DS --> BLEND["混合<br/>半透明, alpha blending"]
    BLEND --> FB["帧缓冲 (Framebuffer)"]
    FB --> POST["后处理<br/>bloom, tone mapping, SSAO"]
    POST --> SWAP["Swapchain<br/>呈现到屏幕"]

    style VS fill:#9cf,stroke:#333
    style FS fill:#fc9,stroke:#333
    style RAST fill:#f99,stroke:#333

GPU 资源生命周期

GPU 资源的典型生命周期:

纹理 (Texture):
    1. 从磁盘加载图像 → 解压缩 → CPU 内存中的像素数组
    2. glCreateTexture / vkCreateImage → 在 GPU 显存中分配
    3. glTexImage2D / vkCmdCopyBufferToImage → 上传到 GPU
    4. 绑定到纹理单元 / descriptor set → 片段着色器采样
    5. 不再使用时释放 (glDeleteTexture / vkDestroyImage)

网格 (Mesh):
    1. 顶点数据 (positions, normals, UVs, tangents) → CPU 内存
    2. 创建 VBO (Vertex Buffer Object) → GPU 显存
    3. 创建 IBO (Index Buffer Object) → 可选索引缓冲
    4. 绑定 VAO (Vertex Array Object) → 描述顶点布局
    5. glDrawElements / vkCmdDrawIndexed → 提交绘制

着色器 (Shader):
    1. GLSL/HLSL 源码 → 编译为 SPIR-V 字节码
    2. 上传到 GPU, 编译为 GPU 特定指令
    3. 绑定到渲染管线的各个阶段

场景图与视锥剔除

场景图 (Scene Graph):
    World
    ├── Room
    │   ├── Table
    │   │   ├── Leg1 (Mesh: "leg.obj", Transform: translate(+1,0,+1))
    │   │   ├── Leg2 (Mesh: "leg.obj", Transform: translate(-1,0,+1))
    │   │   ├── Leg3 (Mesh: "leg.obj", Transform: translate(+1,0,-1))
    │   │   ├── Leg4 (Mesh: "leg.obj", Transform: translate(-1,0,-1))
    │   │   └── Top  (Mesh: "tabletop.obj")
    │   └── Chair (子节点 ...)
    └── Outdoor
        └── Tree (子节点 ...)

视锥剔除 (Frustum Culling):
    对于每个场景节点:
        计算节点的包围盒 (AABB / Bounding Sphere)
        6 个裁剪平面 (左、右、上、下、近、远)
        IF 包围盒在视锥外:
            SKIP → 该节点及其子树都不渲染
        ELIF 包围盒与视锥相交或完全在内部:
            递归检查子节点

    // 加速结构: BVH、八叉树、四叉树优化剔除查询