概念页
计算着色器
Compute Shader
计算着色器是 DirectX 11 引入的一种 GPU 计算方式:它不固定在图形管线的某个位置,但由图形 API 调用,和其他着色器共用统一着色器核心。它暴露了线程组和组内共享内存,最大的优势是能直接处理 GPU 上生成的数据,不用来回传给 CPU。
和 GPU 计算的关系
把 GPU 当作大规模并行处理器来用,叫 GPU 计算,比如 CUDA、OpenCL,可以用来算期权价格、训练神经网络,完全不需要图形功能。计算着色器也是 GPU 计算的一种,但它和渲染紧密结合:由图形 API 调用,和顶点、像素着色器一起使用。
编程模型
- 线程和 warp 在计算着色器里更加可见,每次调用都能拿到自己的线程索引。
- 线程组 (thread group):DirectX 11 中包含 1 到 1024 个线程,用 x、y、z 三维坐标指定,方便在代码里使用。
- 每个线程组有一小块共享内存,DirectX 11 中是 32 KB。
- 按线程组执行,保证组内所有线程同时运行。
为什么快
- 从 GPU 传数据回 CPU 有延迟,计算着色器能让处理过程和结果都留在 GPU 上。
- 共享内存让相邻线程能共享采样像素的中间结果。书中提到,用计算着色器求图像亮度的分布或平均值,比用像素着色器快一倍。
在游戏里的常见用途
- 后处理:模糊、景深等
- 粒子系统
- 网格处理,比如面部动画
- 剔除 (culling)
- 图像过滤、阴影、提高深度精度
- 头发和海浪模拟
- RTR4 提到,有研究认为计算着色器做细分可以比外壳着色器更高效
取舍
计算着色器灵活,但要自己管理线程组大小和共享内存,这些都会影响 GPU 并行架构 里的占用率。
GEA 的视角:核函数(卷 I 4.11.2–4.11.3)
- GEA 把计算着色器看作 SIMD 向量化的延伸:CPU 向量化要把循环改写成每次处理 4/8/16 个元素;写计算核函数则保留单元素(单通道)的循环体,GPU 替你执行循环,每个元素调用一次核函数,类似像素着色器一进一出。
- GEA 用 CUDA C 举例(
__global__核函数、threadIdx.x、<<<G, N>>>指定线程组数和数据维度、cudaDeviceSynchronize()等待完成)。一个线程组只能在一个计算单元上运行,线程组数越多,驱动越能把工作分到多个计算单元。本页 RTR4 讲的是 DirectX 11 的线程组(1–1024 个线程、32 KB 共享内存),两者概念相同,API 不同。详见 GPGPU 编程入门。
GEA 的视角:计算管线在图形中的角色(卷 II 11.4.6.2)
- GEA 把计算管线列为当今 GPU 的四种管线之一(另外三种是传统光栅管线、光线追踪管线和网格着色器管线),四类工作负载可以同时在 GPU 上执行,都能由 CPU 提交,部分还能由 GPU 上的着色器发起(卷 II 11.4.6)。
- 演进逻辑:早期加速卡(Voodoo、GeForce 256)的阶段可配置不可编程;可编程着色器出现后很快统一了编程模型,着色器可以跑在相对通用的 SIMD 核心上,指令集也扩展到通用计算,于是厂商开始支持计算着色器(卷 II 11.4.6.2)。
- 从图形管线角度看,计算着色器既可跑非图形任务,也可实现不便放进光栅管线任何阶段的图形任务,例如 GPU 上的细分曲面和虚幻引擎的 Nanite(见 Nanite 虚拟化几何体)。可以用 HLSL 编写,通过 DirectX 等图形 API 或 OpenCL、CUDA 等非图形 API 配置、编译和调用。
- HLSL 中计算着色器内核是返回
void的函数,接收SV_DispatchThreadID参数,即该通道在线程组中的三维索引(卷 II 11.4.10.1)。原书问题(11.4.10.1):
SV_DispatchThreadID是语义而不是类型(参数类型通常是uint3),而且它是线程在整个 dispatch 中的全局索引,等于SV_GroupID * numthreads + SV_GroupThreadID;线程在本线程组内的索引是SV_GroupThreadID(扁平化后为SV_GroupIndex)(MS Learn "SV_DispatchThreadID"、"SV_GroupThreadID")。
出处
- realtime_rendering_4ed.pdf 第 3 章 The Graphics Processing Unit
- Game_Engine_Architecture_4Ed_-_Jason_Gregory.pdf
- Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 I 第 4 章 4.11 节
- Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
- Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 11 章 11.4.6.2、11.4.10.1 节
相关页面
图形学GPU 并行架构GPU Parallel ArchitectureGPU 为吞吐量而设计:芯片大部分面积是成千上万个着色器核心,而不是缓存和控制逻辑。它靠在大量线程组 (warp/wavefront) 之间快速切换来隐藏访存延迟,用 SIMD 让一组线程锁步执行同一条指令。理解占用率和线程分歧,是写出高效着色器的关键。图形学可编程着色器与 GPU 管线Programmable Shaders & GPU PipelineGPU 把第 2 章的概念管线实现为一组硬件阶段,分为完全可编程、可配置但不可编程、完全固定三类。现代 GPU 采用统一着色器架构:各类着色器共用同一套编程模型和核心,由 GPU 自行分配负载。着色器用 HLSL、GLSL 等类 C 语言编写,输入分为 uniform 和 varying 两类。图形学曲面细分与几何着色器Tessellation & Geometry Shader曲面细分、几何着色器和流输出是顶点着色器之后的三个可选阶段。曲面细分把曲面描述按需生成合适数量的三角形;几何着色器能把图元变成别的图元,但效率不好、实际用得少;流输出把处理后的顶点写回内存以便复用。图形学图像处理与后处理Image Processing & Post-Processing后处理是在渲染出图像后再用 GPU 对其做图像处理:把离屏缓冲当纹理,用全屏 pass 让像素着色器(或计算着色器)对每个像素采样邻域并加权求和。核心技巧包括可分离滤波、利用双线性插值减少采样、降采样、以及借助深度/法线保持边缘的(联合)双边滤波(RTR4 12.1 节)。游戏开发多线程渲染与任务系统Multithreaded Rendering & Task SystemsCPU 时钟频率约在 2003 年停在 3.4 GHz 附近后,性能来自多核。应用阶段的优化一是让代码与内存访问更缓存友好,二是利用多核:多处理器流水线(时间并行,提高吞吐但增加延迟)、并行处理(空间并行,延迟更低)以及两者结合的任务系统;图形 API 用命令缓冲让多个线程并行录制绘制命令,新一代 API(DirectX 12、Vulkan、Metal)把更多责任交给应用以降低驱动开销。图形学遮挡剔除Occlusion Culling遮挡剔除尽早剔除被其他物体挡住的物体,避免它们在 z-buffer 中被光栅化、深度比较甚至着色。本页覆盖遮挡剔除的分类与通用框架、GPU 遮挡查询、层次 Z 缓冲 (HZB) 及其在现代引擎中的简化变体(含两遍法、软件光栅化遮挡),以及在 CPU/GPU 上按物体—簇—三角形多粒度组合剔除并用间接绘制提交的剔除系统。图形学分块着色Tiled Shading分块着色把屏幕划分为瓦片(如 32×32 像素),先为每个瓦片建立可能影响它的光源列表,着色时每个像素在一次着色器调用中只遍历所在瓦片的列表。它可用于延迟着色(tiled deferred),也可用于前向着色(tiled forward,又称 Forward+)。配合 z-prepass 得到的瓦片深度范围可进一步剔除光源,但深度不连续会削弱效果,于是出现 HalfZ、2.5D 剔除等改进。图形学GPU 计算调度与占用率GPU Compute Scheduling & OccupancyGPU 用大量统一的 ALU 以 SIMD/SIMT 方式锁步执行着色程序,ALU 与寄存器文件、L1、本地数据存储、纹理单元等组成多处理器 (MP),由硬件 warp 调度器零开销地切换 warp 以隐藏纹理和内存访问的长延迟。能同时驻留的 warp 数受寄存器等资源限制,用占用率衡量;占用率低会妨碍延迟隐藏,但过高也可能抖动缓存。本页还讨论像素按 quad 调度和 GPU→CPU 回读延迟。游戏开发 · UE5UE5 渲染架构UE5 Rendering ArchitectureUE5 的渲染器是独立的 Renderer 模块,在渲染线程 (Rendering Thread) 上以「场景代理」镜像游戏线程的组件状态,每帧按固定顺序执行深度预通道、G-buffer 基础通道、光照、雾、半透明和后处理。现代渲染代码用渲染依赖图 (Render Dependency Graph, RDG) 声明通道与资源,由 RDG 自动排屏障、复用瞬态内存、并行录制;最终命令经 RHI 线程翻译成 D3D12/Vulkan 等图形 API 调用。默认走延迟着色 (Deferred Shading),也可切换前向着色 (Forward Shading)。图形学文本渲染Text Rendering文本中一个像素的变化就可能把 "l" 变成 "1",因此字形渲染格外讲究。主要路线有:按字号预生成字形位图纹理(配合微调和子像素渲染)、有符号距离场纹理(可在三维表面任意缩放旋转)、以及在 GPU 上直接求值字形曲线。图形学粒子系统Particle Systems粒子系统是一组按某种算法运动的小物体,用于火、烟、爆炸、水流、星系等,同时负责动画(生成、移动、变化、删除)和渲染。粒子通常渲染成公告板;难点在半透明排序、光照(逐顶点、逐像素低分辨率光照图块)以及接收/投射/自阴影(透射率溅射、傅里叶不透明度贴图、消光体积)(RTR4 13.8 节)。图形学高效曲面细分Efficient Tessellation实时渲染曲面需要把它细分成三角网格。与其在 CPU 上细分后传大量三角形,不如把曲面描述送到 GPU,由硬件细分管线(外壳着色器 → 细分器 → 域着色器)展开。本页讲分数细分因子、按曲率/屏幕尺寸/轮廓决定细分率的自适应细分、避免裂缝与跳变的方法,以及 Catmull-Clark 曲面的快速 GPU 渲染(近似面片、OpenSubdiv 特征自适应细分、自适应四叉树)。游戏开发 · UE5Niagara 粒子系统Niagara VFX SystemNiagara 是 UE5 的 VFX 系统,由系统 (System) → 发射器 (Emitter) → 模块 (Module) 的栈式结构组成:发射器按 Emitter Spawn/Update、Particle Spawn/Update、Event、Render 分组,模块是自上而下执行、基于 HLSL 的「读-算-写」单元。继承、动态输入、事件和数据接口 (Data Interface) 提供复用与外部数据访问;发射器可选 CPU 或 GPU 计算着色器模拟。官方 5.8 文档未找到 CPU/GPU 对比页,相关取舍按通识标注。图形学GPGPU 编程入门Introduction to GPGPU ProgrammingGEA 把 GPGPU 讲成「SIMD 向量化推到极致」:GPU 结合 SIMD(向量化 ALU)与 MIMD(一种抢占式多线程),即 NVIDIA 所说的 SIMT。适合 GPU 的任务必须是数据并行的——每个元素的计算不依赖其他元素的结果。写法与 CPU 向量化相反:不把循环硬编码成每次 4/8/16 个,而是保留单通道的循环体,抽成计算核函数 (compute kernel),由 GPU 替我们「跑循环」。一个「GPU 线程」其实就是一条 SIMD 通道。图形学网格着色器管线Mesh Shader Pipeline网格着色器管线(也叫网格几何管线)是 GPU 厂商为取代传统光栅管线前段而推出的新架构:光栅化器和像素着色器不变,网格着色器和可选的放大着色器(任务着色器)接管顶点、外壳、域和几何着色器的全部工作。它以类似计算着色器的线程组处理叫 meshlet 的小批图元,像启动计算着色器一样启动绘制,还能把部分应用层工作搬到 GPU 上。2019 年进入 DirectX 12,2022 年以 VKEXTmeshshader 扩展进入 Vulkan。游戏开发 · UE5Nanite 虚拟化几何体Nanite Virtualized GeometryNanite 是 UE5 的虚拟化几何体 (Virtualized Geometry) 系统:导入时把网格切成分层的三角形簇 (Cluster),渲染时按相机视角逐簇选择细节层次并无缝拼接,按需从磁盘流送,并在绕过传统绘制调用 (Draw Call) 的独立通道中渲染,使帧预算不再受多边形数、绘制调用和网格内存约束。游戏开发 · UE5PCG 程序化内容生成框架PCG FrameworkPCG 框架把程序化内容表达为「点流」:PCG 组件/体积从关卡采样空间数据,图中的 Sampler 生成带变换、密度、种子与自定义属性的点,经过滤与变换后由 Spawner 生成网格或 Actor,编辑器中实时更新,也可运行时生成。属性分为 $ 静态属性和元数据动态属性,按 @Data/@Points/@Elements 域组织;图参数与图实例的用法类似材质参数与材质实例;与世界分区集成,生成物继承数据层与 HLOD 层。