顶点着色器
定义
顶点着色器是图形处理流水线中直接由程序员控制的第一道处理阶段,其作用对象是逐个输入的顶点,而非由顶点拼成的三角形面片[1]。它是一段运行在 GPU 上的小程序,每送入一个顶点就执行一次,输入为该顶点携带的各项属性,例如位置、法线、颜色和纹理坐标[4]。
顶点着色器的输出同样是一组顶点属性。其中必须写入的是顶点在齐次裁剪空间中的位置,这一坐标会被后续的图元装配、裁剪和光栅化使用;此外还可以输出纹理坐标、顶点颜色、雾化因子等自定义数据,这些值经插值后交给片元阶段[5][2]。一份最小可用的顶点着色器,至少要完成齐次裁剪坐标的输出[1]。
原理
图形管线在逻辑上分作若干阶段:顶点着色器接收顶点属性,之后经过图元装配、裁剪、光栅化,再由片元着色器处理每个片段,最后写入帧缓冲[6][7]。顶点着色器处在几何处理的开端,其典型计算是把模型空间中的顶点坐标依次经过世界变换、观察变换和投影变换,得到裁剪空间坐标,即 $P_{clip} = M_{proj} \cdot M_{view} \cdot M_{model} \cdot P_{model}$[2][8]。
处理过程中的数据分为两类:随顶点变化的数据是逐顶点输入,例如位置、法线、纹理坐标;在一次绘制调用内保持不变的数据是常量参数,例如模型矩阵、视图矩阵、材质颜色与光照方向,通常以 uniform 变量形式传入[5][4]。
顶点之间彼此独立:着色器不能增加或删除顶点,一个顶点得到的结果也无法传给另一个顶点,因此 GPU 可以把大批顶点并行分派给多个着色器核处理[1]。在统一渲染架构中,顶点任务常被成批打包,例如每 32 个顶点组成一个着色任务,以单指令多线程的方式在着色器核上执行[9]。
Mermaid 形式的数据流向可表示为:
flowchart LR
A[顶点属性数据] --> B[顶点着色器]
B --> C[图元装配]
C --> D[裁剪]
D --> E[光栅化]
E --> F[片元着色器]
F --> G[帧缓冲]
发展历程
在可编程管线出现之前,GPU 采用固定功能流水线。1999 年英伟达(NVIDIA)推出的 GeForce 256 把变换与光照(T&L)计算从 CPU 移到专用硬件,但开发者无法编写自定义代码,顶点处理只能按预设顺序执行[10][11]。
微软于 2000 年 11 月发布的 DirectX 8.0 定义了 Shader Model 1.0,规定了可编程的顶点着色器和像素着色器[10]。2001 年 2 月,英伟达发布代号 NV20 的 GeForce 3,成为首款在硬件上支持可编程顶点着色器的消费级 GPU,通过 nFiniteFX 引擎支持 Vertex Shader 1.1[12][13]。这一时期的着色器以类似汇编的语言编写,且不支持分支等流控制[13]。
2002 年发布的 DirectX 9 带来 Shader Model 2.0,顶点与像素着色器具备了更通用的可编程能力,并引入类 C 语言 HLSL,取代了此前接近汇编的写法[10][11]。此后的 Shader Model 3.0 为顶点程序加入了纹理读取与动态分支能力;2007 年前后的 Shader Model 4.0 采用统一渲染架构,顶点与像素着色器规格趋于一致,并支持 32 位浮点运算[11]。在 OpenGL 一侧,2004 年发布的 OpenGL 2.0 正式纳入 GLSL 着色语言,使顶点着色器可以用高级语言编写[14]。
应用
顶点着色器最常见的用途是完成坐标变换与逐顶点光照,从而搭建三维场景的几何骨架[3][2]。在动画制作中,它可借助顶点混合实现骨骼蒙皮与形变动画,用于表现角色身体与面部的运动[1]。
顶点级程序也用于程序化形变,例如旗帜、布料与水面的飘动,以及地形高度场的呈现;通过只创建一次网格并让着色器反复变形,可以生成物体轮廓与粒子效果[1]。此外,把整帧内容作为纹理映射到经程序变形的屏幕网格上,能够实现镜头畸变、热雾、水波纹与页面卷曲等画面效果[1]。
在网页等场景中,着色器程序通常由应用侧提前生成并按需复用,以减少渲染所需的时长,这些程序由顶点着色器与片元着色器成对组织,再交由 GPU 执行[15]。
局限
顶点着色器只处理顶点,无法获知哪些顶点会组成三角形,也不能改变图元的类型或顶点的连接顺序[1][16]。它在一次执行中既不能生成新顶点,也不能丢弃已有顶点,因此要按几何体之间的关系增减图元,需要依靠后续的几何着色器等阶段[1][10]。
由于顶点之间相互独立,顶点着色器无法让一个顶点的计算结果影响另一个顶点,也就难以直接在着色器内完成需要全局信息的计算[1]。早期版本还缺少流控制和依赖纹理读取等能力,表现力受到限制,只能通过计算两个分支结果再做选择来模拟条件判断[13]。
在分块渲染等架构中,若在几何处理阶段缓存顶点着色结果,会增加显存占用与带宽消耗;若在渲染阶段重复调用顶点着色器,又会增加 GPU 运算量并影响性能,两种做法都需要权衡[3]。此外,顶点着色的精度与计算量直接关系渲染开销,早期的分离式架构中顶点与像素单元比例固定,容易在顶点密集或像素密集的场景中出现资源闲置[11]。
参见
参考资料
- 社区首页 >专栏 >《实时渲染》第3章-图形处理单元-3.5顶点着色器 [引用日期2026-10-29]
- 裁剪坐标的透视除法 [引用日期2026-10-29]
- 1)顶点着色器:顶点着色器是GPU渲染流程中的第一个阶段,也是一个可编程处理器 [引用日期2026-10-29]
- Vertex Shaders [引用日期2026-10-29]
- 在 Direct3D 9 撰寫 HLSL 著色器 [引用日期2026-10-29]
- google.com 上的网页 [引用日期2026-10-29]
- CN105321199B(PDF) [引用日期2026-10-29]
- OpenGL可编程管线 [引用日期2026-10-29]
- 该三维图形处理器采用统一渲染架构,顶点着色器和像素着色器在同一个着色器核中同时执行,因此它们共享相同的数据通路 [引用日期2026-10-29]
- Part I: The first fully programmable GPUs—a review [引用日期2026-10-29]
- 着色器模型变化历程与总结 - 浅析DirectX11技术带给图形业界的改变 [引用日期2026-10-29]
- GeForce 3 series [引用日期2026-10-29]
- 《实时渲染》第3章-图形处理单元-3.4可编程着色和及其API的演变 [引用日期2026-10-29]
- GPU programming (shaders) [引用日期2026-10-29]
- [0158] 本说明书实施例所述的着色器程序可包括多个顶点着色器和多个片段着色器,一个顶点着色器对应一个片段着色器 [引用日期2026-10-29]
- Programmable Graphics Hardware: History [引用日期2026-10-29]