概念页
顶点着色器
Vertex Shader
顶点着色器是程序员直接控制的第一个管线阶段,逐个处理输入顶点,至少要输出顶点在齐次裁剪空间里的位置。它不能创建或删除顶点,顶点之间也不能传递结果,正因如此可以大规模并行。
输入装配 (Input Assembler)
在顶点着色器之前,DirectX 的输入装配器会把多个数据流编织成顶点和图元。比如一个物体可以由一个位置数组和一个颜色数组组成;另一个物体可以复用同一个位置数组,配上不同的模型变换和颜色数组。输入装配器也支持实例化 (instancing):一次 draw call 把同一个物体画多次,每个实例带有不同的数据。
物理实现上,取数据组装顶点这一步可能就在顶点着色器里完成,驱动会悄悄在每个着色器前面插入对应指令,程序员看不到。
为什么法线定义在顶点上
数学上每个三角形都有明确的法线,但三角网格通常是用来近似一个曲面的,顶点法线表达的是曲面在该点的朝向,而不是三角形本身。想要表现锐利的折边时,就把那个顶点复制一份,给两个不同的法线。
规则
- 只处理顶点,看不到三角形由哪些顶点组成。
- 可以修改、创建或忽略顶点的颜色、法线、纹理坐标、位置等数据。
- 通常把顶点从模型空间变换到齐次裁剪空间,这是必须的输出(见 坐标空间)。
- 不能创建或销毁顶点,一个顶点的结果不能传给另一个顶点。
- 输出值会在三角形或线段上插值,传给后续阶段。
在游戏里的常见用途
- 只建一次网格,用顶点着色器变形出不同物体
- 角色身体和面部动画:蒙皮 (skinning) 和变形 (morphing)
- 程序化变形:旗帜、布料、水面的运动
- 粒子:送入没有面积的退化网格,再在着色器里撑开
- 镜头畸变、热浪、水波纹、翻页:把整个帧缓冲当成纹理贴到一个屏幕对齐的网格上,再做程序化变形
- 地形:用顶点纹理读取 (vertex texture fetch) 读取高度图
GEA 的视角:顶点属性与顶点着色器(卷 II 11.3.6.2、11.4.6.1)
常见顶点属性
GEA 列出的典型属性(卷 II 11.3.6.2),渲染工程师可以按效果需要自行增加:
| 属性 | 说明 |
|---|---|
| 位置 | 通常在模型空间中给出 |
| 顶点法线 | 逐顶点动态光照用 |
| 切线 、副切线 | 与法线两两垂直,构成切线空间,用于法线贴图、环境贴图等逐像素计算(见 法线贴图与凹凸贴图) |
| 漫反射色 | RGBA,含不透明度;可离线(静态光照)或运行时算出 |
| 镜面色 | 镜面高光颜色 |
| 纹理坐标 或 | 一个三角形可有多套,对应多张纹理 |
| 蒙皮权重 | 关节索引与权重,可受多个关节影响(见 顶点混合与蒙皮) |
顶点着色器的职责与规则
- 负责把顶点从模型或世界空间变到观察空间,再投影到齐次裁剪空间;也常在这里做逐顶点光照,这就是早期厂商所说的"硬件 T&L"(变换与光照)的来历。
- 也可以做任意逐顶点计算:骨骼蒙皮,或用高度图、水面模拟把预先细分的水平网格变成起伏的地形或水面。
- 每个输入顶点必须输出一个顶点。输入输出都是 C 风格结构体,格式不必相同;输入至少要有位置,输出至少要有齐次裁剪空间位置。
- 概念上每个顶点调用一次,但因为顶点被多个三角形共享、顶点缓存容量有限,实际可能被调用多次(卷 II 11.4.6.1 脚注)。这正是 三角形带、扇与索引网格 中顶点缓存优化要解决的问题。
出处
- realtime_rendering_4ed.pdf 第 3 章 The Graphics Processing Unit
- Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
- Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 11 章 11.3.6.2、11.4.6.1 节
相关页面
图形学可编程着色器与 GPU 管线Programmable Shaders & GPU PipelineGPU 把第 2 章的概念管线实现为一组硬件阶段,分为完全可编程、可配置但不可编程、完全固定三类。现代 GPU 采用统一着色器架构:各类着色器共用同一套编程模型和核心,由 GPU 自行分配负载。着色器用 HLSL、GLSL 等类 C 语言编写,输入分为 uniform 和 varying 两类。图形学坐标空间Coordinate Spaces顶点从模型到屏幕要依次经过模型空间、世界空间、观察空间、裁剪空间、标准化设备坐标 (NDC)、窗口坐标。每一步变换都有明确目的,大部分可以用 4×4 矩阵表示并相乘合并。图形学曲面细分与几何着色器Tessellation & Geometry Shader曲面细分、几何着色器和流输出是顶点着色器之后的三个可选阶段。曲面细分把曲面描述按需生成合适数量的三角形;几何着色器能把图元变成别的图元,但效率不好、实际用得少;流输出把处理后的顶点写回内存以便复用。游戏美术顶点混合与蒙皮Vertex Blending & Skinning顶点混合(也叫线性混合蒙皮、enveloping、骨骼子空间变形)让一个顶点受多根骨骼的变换影响,按权重混合结果,使关节处的"皮肤"连续弯曲。它非常适合在 GPU 上执行;主要缺点是关节折叠、扭转和自相交,可用双四元数蒙皮等方法改善。游戏美术变形动画Morphing变形在两个模型之间插值,需要解决顶点对应和插值两个问题。顶点一一对应时可以逐顶点线性插值;更直观可控的形式是变形目标/混合形状:在中性模型上叠加加权的差分向量,常用于面部动画。过场中无法用这些方法表达的动画,可以用压缩后的几何缓存逐帧回放。游戏数学基本仿射变换Basic Affine Transforms平移、旋转、缩放、切变是摆放和变形物体的基础矩阵;它们的连乘顺序有关、但满足结合律。刚体变换的逆可以直接写出,法线要用伴随矩阵的转置(传统说法是逆转置)变换。理解这些矩阵的性质能写出更快、更正确的变换代码。图形学三角形带、扇与索引网格Triangle Strips, Fans & Indexed Meshes让共享顶点的三角形成组送入管线,可以减少顶点着色器调用。三角形扇和带把每三角形发送的顶点数降到接近 1;现代 GPU 的标准做法是带单一索引缓冲的三角形网格,理论上每三角形只需处理约 0.5 个顶点,实际效果取决于变换后顶点缓存,由三角形顺序优化(Forsyth、Tipsify 等)决定。图形学轮廓边与几何描边Contour Edges & Geometric Outlining卡通渲染的黑色描边可以按表面着色、过程几何、图像处理、几何边检测或混合方式生成。本页讲边的分类,以及在几何层面生成描边的三类方法:基于着色法线、背面过程几何(偏移、膨胀、外壳)、显式检测轮廓边并做隐藏线消除。图像空间方法见 图像空间边缘检测。图形学地形渲染Terrain Rendering地形渲染(游戏、Google Earth、开源大世界引擎 Cesium 等)要在巨大高度场上按距离分配细节,同时控制内存、绘制调用和 LOD 之间的裂缝与跳变。主流 GPU 友好方案有:类似纹理 clipmap 的几何 clipmap、按瓦片复用顶点缓冲只换索引缓冲的分块方案、基于四叉树和屏幕空间误差的 chunked LOD、预存所有过渡索引缓冲的受限四叉树,以及 GPU 细分和压缩等补充手段。任何方案都可叠加分形噪声以在拉近时提供细节,许多系统也在加载时程序化生成地形。图形学网格整合与顶点法线Mesh Consolidation & Vertex Normals整合 (consolidation) 指把零散多边形合并成共享顶点的网格、让所有面朝向一致、判断是否为实体,并生成平滑的顶点法线与折痕边。这些步骤是背面剔除、折痕检测、阴影体、碰撞检测、3D 打印等的前提。图形学顶点压缩与精度Vertex Compression & Precision网格数据像纹理一样可以压缩:传输用的整体压缩(Draco 等)一次性解码,渲染用的定长压缩让顶点着色器在 GPU 上逐顶点解码,从而降低内存、带宽并改善缓存。另一面是精度问题:大世界中单一坐标系会让远离原点的物体抖动,需要相对相机的变换或分段原点。图形学着色频率与材质系统Shading Frequency & Material Systems实现着色时要按"计算频率"划分工作:整个 draw call 不变的放到应用端作为 uniform,其余放在相应的可编程阶段。实践中大多数着色在像素级完成,顶点着色器负责变换和变形。材质系统把面向美术的材质与底层着色器组织起来,处理海量着色器变体的组合问题。图形学法线贴图与凹凸贴图Normal & Bump Mapping凹凸贴图是一类在像素着色中修改着色法线来表现中尺度细节的技术:几何法线不变,只改变光照计算使用的法线,从而在不增加几何的情况下显得更立体。最常用的形式是切线空间法线贴图,需要每顶点的切线框架;法线贴图的过滤是难点。图形学渲染管线Rendering Pipeline渲染管线是实时图形的核心:给定虚拟相机、三维物体、光源等,把场景转换成一张二维图像。RTR4 把它粗分为四个功能阶段:应用、几何处理、光栅化、像素处理,各阶段并行执行,整体速度由最慢的阶段决定。