# 游戏渲染管线与着色器 Confidence: high Last verified: 2026-04-28 Generation: human_only # 游戏渲染管线与着色器 ## 概述 渲染管线(Rendering Pipeline)是将3D场景转换为2D图像的一系列处理步骤。理解渲染管线对于优化性能、实现视觉效果和跨平台开发至关重要。 --- ## 1. 渲染管线基础 ### 1.1 Forward Rendering(前向渲染) **原理**:对每个物体,遍历所有光源计算光照 ``` 对于每个物体: 对于每个像素: 对于每个光源: 计算光照贡献 累加所有光照 ``` **优点**: - 简单直观 - 支持透明物体 - 内存占用低 **缺点**: - 光源数量增加时性能急剧下降(O(n×m)) - 重复计算(多个物体在同一像素) **适用场景**: - 移动游戏 - 光源少的场景 - 需要大量透明物体的游戏 ### 1.2 Deferred Rendering(延迟渲染) **原理**:先渲染几何信息到G-Buffer,再统一计算光照 ``` Pass 1 - 几何 Pass: 渲染所有物体到 G-Buffer G-Buffer 包含:位置、法线、颜色、材质属性 Pass 2 - 光照 Pass: 对每个光源: 在光源影响范围内计算光照 读取 G-Buffer 数据 ``` **优点**: - 光源数量对性能影响小 - 每个像素只计算一次几何 - 适合大量光源场景 **缺点**: - 内存占用高(G-Buffer) - 不支持 MSAA(多重采样抗锯齿) - 透明物体需要单独处理 **适用场景**: - 开放世界游戏 - 室内场景(多光源) - PC/主机游戏 ### 1.3 Forward+ / Tiled Forward Rendering **原理**:结合 Forward 和 Deferred 的优点 ``` 1. 将屏幕划分为 Tile(通常 16x16 像素) 2. 对每个 Tile,计算影响它的光源列表 3. 前向渲染,但每个像素只计算相关光源 ``` **优点**: - 支持大量光源(比 Forward 多) - 支持 MSAA - 支持透明物体 - 内存占用适中 **适用场景**: - 现代游戏的主流选择 - Unity URP、Unreal 默认管线 ### 1.4 Clustered Rendering **原理**:在 Tile 的基础上增加深度维度 ``` 1. 将视锥体划分为 3D 簇(Cluster) 2. 每个 Cluster 存储影响它的光源列表 3. 渲染时根据像素深度确定 Cluster,只计算相关光源 ``` **优点**: - 支持极大量光源 - 更好的深度剔除 - 适合复杂室内场景 **适用场景**: - 高端 PC/主机 - Unity HDRP、Unreal 5 ### 1.5 管线对比 | 特性 | Forward | Deferred | Forward+ | Clustered | |------|---------|----------|----------|-----------| | **光源数量** | < 10 | 100+ | 100+ | 1000+ | | **透明物体** | 原生支持 | 需额外处理 | 原生支持 | 原生支持 | | **MSAA** | 支持 | 不支持 | 支持 | 支持 | | **内存占用** | 低 | 高 | 中 | 中 | | **带宽** | 低 | 高 | 中 | 中 | | **复杂度** | 低 | 中 | 中 | 高 | --- ## 2. 着色器编程 ### 2.1 着色器类型 | 类型 | 阶段 | 用途 | |------|------|------| | **Vertex Shader** | 顶点处理 | 变换、变形、骨骼动画 | | **Fragment/Pixel Shader** | 片元处理 | 光照、纹理采样、颜色计算 | | **Geometry Shader** | 图元处理 | 生成额外几何(粒子、毛发) | | **Compute Shader** | 通用计算 | 后处理、物理、AI | | **Tessellation Shader** | 细分处理 | 动态 LOD、曲面细分 | ### 2.2 HLSL 示例(Unity/Unreal) ```hlsl // 基础 PBR 片元着色器(HLSL) struct VertexInput { float4 position : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; }; struct VertexOutput { float4 position : SV_POSITION; float3 worldNormal : NORMAL; float2 uv : TEXCOORD0; float3 worldPosition : TEXCOORD1; }; // 顶点着色器 VertexOutput VertexShader(VertexInput input) { VertexOutput output; output.position = mul(UNITY_MATRIX_MVP, input.position); output.worldNormal = mul((float3x3)unity_ObjectToWorld, input.normal); output.uv = input.uv; output.worldPosition = mul(unity_ObjectToWorld, input.position).xyz; return output; } // 片元着色器 float4 FragmentShader(VertexOutput input) : SV_TARGET { // 采样纹理 float4 albedo = tex2D(_MainTex, input.uv); float3 normal = normalize(input.worldNormal); // 基础光照计算(Lambert) float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); float NdotL = max(dot(normal, lightDir), 0); // 最终颜色 float3 diffuse = albedo.rgb * NdotL * _LightColor0.rgb; float3 ambient = albedo.rgb * UNITY_LIGHTMODEL_AMBIENT.rgb; return float4(diffuse + ambient, albedo.a); } ``` ### 2.3 GLSL 示例(OpenGL/WebGL) ```glsl // 顶点着色器(GLSL) #version 300 es in vec3 a_position; in vec3 a_normal; in vec2 a_uv; uniform mat4 u_modelMatrix; uniform mat4 u_viewMatrix; uniform mat4 u_projectionMatrix; out vec3 v_worldNormal; out vec2 v_uv; out vec3 v_worldPosition; void main() { vec4 worldPosition = u_modelMatrix * vec4(a_position, 1.0); gl_Position = u_projectionMatrix * u_viewMatrix * worldPosition; v_worldNormal = mat3(u_modelMatrix) * a_normal; v_uv = a_uv; v_worldPosition = worldPosition.xyz; } // 片元着色器(GLSL) #version 300 es precision highp float; in vec3 v_worldNormal; in vec2 v_uv; in vec3 v_worldPosition; uniform sampler2D u_mainTex; uniform vec3 u_lightDir; uniform vec3 u_lightColor; out vec4 fragColor; void main() { vec4 albedo = texture(u_mainTex, v_uv); vec3 normal = normalize(v_worldNormal); float NdotL = max(dot(normal, -u_lightDir), 0.0); vec3 diffuse = albedo.rgb * NdotL * u_lightColor; fragColor = vec4(diffuse, albedo.a); } ``` ### 2.4 Shader Graph / 可视化着色器 | 工具 | 引擎 | 特点 | |------|------|------| | **Shader Graph** | Unity | 节点图,支持 URP/HDRP | | **Material Editor** | Unreal | 节点图,功能强大 | | **VisualShader** | Godot | 节点图,轻量 | --- ## 3. 光照模型 ### 3.1 PBR(基于物理的渲染) PBR 是现代游戏的标准光照模型,基于物理原理而非经验公式。 **核心概念**: - **Albedo(反照率)**:基础颜色,无光照信息 - **Metallic(金属度)**:0 = 非金属,1 = 金属 - **Roughness(粗糙度)**:0 = 镜面,1 = 漫反射 - **Normal(法线)**:表面微观几何 - **AO(环境光遮蔽)**:自遮挡阴影 **工作流程**: | 工作流 | Albedo | Specular | 特点 | |--------|--------|----------|------| | **Metallic-Roughness** | 包含金属色 | 自动生成 | 更常见,更直观 | | **Specular-Glossiness** | 纯漫反射 | 单独贴图 | 更灵活,但易出错 | ```hlsl // 简化的 PBR 漫反射计算 float3 Diffuse_Lambert(float3 albedo) { return albedo / PI; } // 简化的 PBR 镜面反射(Blinn-Phong 近似) float3 Specular_BlinnPhong(float3 specularColor, float roughness, float3 normal, float3 viewDir, float3 lightDir) { float3 halfDir = normalize(lightDir + viewDir); float NdotH = max(dot(normal, halfDir), 0); float specPower = exp2(10 * (1 - roughness) + 1); return specularColor * pow(NdotH, specPower); } ``` ### 3.2 IBL(基于图像的光照) 使用环境贴图模拟间接光照: ``` 环境 HDR 贴图 ↓ 预计算漫反射辐照度(Irradiance Map) 预计算镜面反射(Prefiltered Mipmaps) ↓ 运行时采样 ``` ### 3.3 Ray Tracing(光线追踪) 实时光线追踪是现代 GPU 的重要特性: | 效果 | 说明 | 性能影响 | |------|------|----------| | **Ray Traced Reflections** | 精确反射 | 高 | | **Ray Traced Shadows** | 柔和阴影 | 中 | | **Ray Traced GI** | 全局光照 | 极高 | | **Ray Traced Ambient Occlusion** | 环境光遮蔽 | 中 | **硬件支持**: - NVIDIA RTX(Turing+) - AMD RDNA2+ - Intel Arc ### 3.4 Global Illumination(全局光照) | 技术 | 原理 | 质量 | 性能 | |------|------|------|------| | **Lightmap** | 预计算静态光照 | 高 | 运行时零开销 | | **Light Probe** | 预计算动态物体采样点 | 中 | 低 | | **Realtime GI** | 实时计算间接光 | 中 | 高 | | **Lumen**(Unreal 5) | 软件光线追踪 | 高 | 中高 | | **DDGI** | 动态漫反射全局光照 | 高 | 中 | --- ## 4. 后处理技术 ### 4.1 常见后处理效果 | 效果 | 说明 | 性能 | |------|------|------| | **Bloom** | 高亮区域泛光 | 中 | | **SSAO** | 屏幕空间环境光遮蔽 | 中 | | **TAA** | 时域抗锯齿 | 中 | | **Motion Blur** | 运动模糊 | 中 | | **Depth of Field** | 景深 | 高 | | **Chromatic Aberration** | 色差 | 低 | | **Vignette** | 暗角 | 低 | | **Color Grading** | 调色 | 低 | ### 4.2 抗锯齿技术 | 技术 | 原理 | 质量 | 性能 | 模糊 | |------|------|------|------|------| | **MSAA** | 多重采样 | 高 | 高 | 无 | | **FXAA** | 快速近似 | 低 | 极低 | 有 | | **SMAA** | 形态学抗锯齿 | 中 | 低 | 轻微 | | **TAA** | 时域累积 | 高 | 中 | 轻微 | | **DLSS/FSR/XeSS** | AI/算法超采样 | 极高 | 负(提升性能) | 无 | ### 4.3 超采样技术 | 技术 | 厂商 | 原理 | 性能提升 | |------|------|------|----------| | **DLSS** | NVIDIA | AI 重建高分辨率 | 2-3x | | **FSR** | AMD | 算法 upscale | 2x | | **XeSS** | Intel | AI/算法混合 | 2x | | **TSR** | Unreal | 时域超分辨率 | 2x | --- ## 5. 性能优化 ### 5.1 Draw Call 优化 | 技术 | 原理 | 效果 | |------|------|------| | **Static Batching** | 合并静态物体 | 减少 Draw Call | | **Dynamic Batching** | 运行时合并小物体 | 减少 Draw Call | | **GPU Instancing** | 一次绘制多个相同物体 | 大幅减少 Draw Call | | **SRP Batcher** | 持续绑定材质数据 | 减少 CPU 开销 | | **GPU Driven Rendering** | GPU 直接处理剔除 | 极大量物体 | ```csharp // Unity GPU Instancing 示例 public class GPUInstancing : MonoBehaviour { public Mesh mesh; public Material material; public int instanceCount = 1000; private Matrix4x4[] matrices; void Start() { matrices = new Matrix4x4[instanceCount]; for (int i = 0; i < instanceCount; i++) { Vector3 position = Random.insideUnitSphere * 50f; Quaternion rotation = Random.rotation; Vector3 scale = Vector3.one * Random.Range(0.5f, 2f); matrices[i] = Matrix4x4.TRS(position, rotation, scale); } // 启用 GPU Instancing material.enableInstancing = true; } void Update() { // 批量绘制 Graphics.DrawMeshInstanced(mesh, 0, material, matrices); } } ``` ### 5.2 遮挡剔除(Occlusion Culling) ```csharp // Unity 遮挡剔除设置 public class OcclusionCullingSetup : MonoBehaviour { void Start() { // 标记为静态遮挡物 gameObject.isStatic = true; // 烘焙遮挡剔除数据 // Window -> Rendering -> Occlusion Culling -> Bake } } ``` ### 5.3 LOD(Level of Detail) ```csharp // Unity LOD Group 设置 public class LODSetup : MonoBehaviour { void Start() { LODGroup lodGroup = gameObject.AddComponent(); LOD[] lods = new LOD[3]; // LOD 0:0-50% 距离,高质量模型 lods[0] = new LOD(0.5f, new Renderer[] { highQualityMesh }); // LOD 1:50-20% 距离,中质量模型 lods[1] = new LOD(0.2f, new Renderer[] { mediumQualityMesh }); // LOD 2:20% 以下距离,低质量模型/ Billboard lods[2] = new LOD(0.05f, new Renderer[] { lowQualityMesh }); lodGroup.SetLODs(lods); lodGroup.RecalculateBounds(); } } ``` ### 5.4 性能预算检查清单 | 指标 | 移动端 | PC | 主机 | |------|--------|-----|------| | Draw Calls | < 100 | < 2000 | < 5000 | | 三角面数 | < 100K | < 5M | < 10M | | 纹理内存 | < 200MB | < 2GB | < 4GB | | Shader 复杂度 | 简单 | 复杂 | 复杂 | | 后处理 | 少量 | 完整 | 完整 | --- ## 6. 跨平台渲染 ### 6.1 图形 API 对比 | API | 平台 | 特点 | |-----|------|------| | **DirectX 12** | Windows/Xbox | 低开销,多线程 | | **Vulkan** | 跨平台 | 低开销,显式控制 | | **Metal** | Apple | 低开销,Apple 优化 | | **OpenGL ES** | 移动端 | 广泛支持,逐渐淘汰 | | **WebGPU** | Web | 现代 Web 图形 | ### 6.2 跨平台着色器 ```hlsl // Unity ShaderLab - 跨平台着色器 Shader "Custom/CrossPlatform" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color ("Color", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag // Unity 自动处理平台差异 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; }; TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _Color; Varyings vert(Attributes input) { Varyings output; output.positionCS = TransformObjectToHClip(input.positionOS.xyz); output.uv = input.uv; return output; } half4 frag(Varyings input) : SV_TARGET { half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv); return col * _Color; } ENDHLSL } } } ``` --- ## 7. 典型游戏渲染案例分析 ### 7.1 《赛博朋克 2077》 **渲染技术**: - 光线追踪反射/阴影/全局光照 - DLSS 2.0/3.0 - 复杂的材质系统 - 大规模开放世界流送 ### 7.2 《艾尔登法环》 **渲染技术**: - 自定义引擎(FromSoftware) - 大气散射 - 动态天气 - 大规模地形渲染 ### 7.3 《原神》 **渲染技术**: - Unity 自定义渲染管线 - 卡通渲染(Toon Shading) - 跨平台优化(移动/PC/主机) - 动态分辨率 **卡通渲染关键**: ```hlsl // 卡通着色器核心 half4 ToonShading(float3 normal, float3 lightDir, half4 albedo) { half NdotL = dot(normal, lightDir); // 硬边光影(而非平滑过渡) half toonRamp = smoothstep(0.0, 0.1, NdotL); // 多级阴影 if (NdotL < 0.3) toonRamp = 0.3; // 暗部 else if (NdotL < 0.6) toonRamp = 0.6; // 中间调 else toonRamp = 1.0; // 亮部 // 边缘光(Rim Light) half rim = 1.0 - saturate(dot(viewDir, normal)); half3 rimColor = pow(rim, 3) * _RimColor; return half4(albedo.rgb * toonRamp + rimColor, albedo.a); } ``` --- ## 8. 渲染系统检查清单 ### 8.1 设计阶段 - [ ] 确定目标平台和性能预算 - [ ] 选择渲染管线(Forward/Deferred/Forward+) - [ ] 定义视觉风格(写实/卡通/像素) - [ ] 规划光照策略(实时光/烘焙/混合) ### 8.2 实现阶段 - [ ] 设置渲染管线 - [ ] 创建主着色器 - [ ] 配置光照系统 - [ ] 实施后处理效果 - [ ] 设置 LOD 系统 ### 8.3 优化阶段 - [ ] 分析 Draw Call - [ ] 优化材质和着色器 - [ ] 配置遮挡剔除 - [ ] 压缩纹理 - [ ] 测试目标平台性能 --- ## 参考来源 - Unity Scriptable Render Pipeline 官方文档 - Unreal Rendering 官方文档 - Godot Rendering 官方文档 - 《Real-Time Rendering》— Tomas Akenine-Möller - 《Physically Based Rendering》— Matt Pharr - GDC 演讲:《The Rendering of The Last of Us Part II》 - SIGGRAPH 论文:各种渲染技术