【URP】UnityHLSL顶点片元语义详解
【从UnityURP开始探索游戏渲染】专栏-直达
发展历史
传统可编程管线语义体系早期Unity采用HLSL/CG混合语法,定义了基础语义系统:
- 顶点着色器输入语义:
POSITION、NORMAL、TEXCOORD0等用于接收模型数据 - 输出语义:
SV_POSITION传递裁剪空间坐标,COLOR0等自定义语义用于插值数据传递 - 片元着色器输出语义:
SV_Target控制颜色缓冲区写入
URP架构的语义重构2021年推出的URP通过SRP体系重构了语义系统:
- 引入
UNITY_MATRIX_MVP等宏替代传统矩阵传递方式,优化实例化渲染效率 - 标准化顶点着色器输入结构体,强制要求
positionOS(模型空间坐标)作为基础输入 - 新增语义支持屏幕空间坐标转换,如
COMPUTE_SCREEN_POS宏实现positionCS计算
现代URP语义特性当前URP 12.x版本语义系统呈现以下特征:
- 保留传统语义兼容性(如
TEXCOORD系列) - 强化系统语义(
SV_Position用于深度计算,SV_RenderTargetArrayIndex支持多目标渲染) - 通过
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"预定义语义宏,实现跨平台兼容
该演进过程体现了从灵活语义定义到标准化渲染接口的转变,同时保持了与旧版管线的兼容性。开发者可通过URP
顶点着色器输入数据由应用阶段(如Mesh Renderer)提供,常用语义如下:
| 语义 | 数据类型 | 描述 |
|---|---|---|
POSITION |
float4 |
模型空间顶点坐标 |
NORMAL |
float3 |
模型空间法线向量 |
TANGENT |
float4 |
模型空间切线向量(.w分量存储副切线方向标志) |
TEXCOORDn |
float2/float4 |
顶点纹理坐标(n=0-7,如TEXCOORD0表示第一组UV) |
COLOR |
fixed4/float4 |
顶点颜色 |
示例代码:
hlsl
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
🔄 顶点着色器输出/片元着色器输入语义
顶点着色器向片元着色器传递数据时需定义插值语义:
| 语义 | 数据类型 | 描述 |
|---|---|---|
SV_POSITION |
float4 |
必需语义,输出裁剪空间顶点坐标 |
TEXCOORDn |
任意 |
自定义插值数据(如UV、计算中间值),n=0-7 |
COLORn |
fixed4/float4 |
插值颜色(n=0-1) |
注意事项:
SV_POSITION必须存在于顶点着色器输出结构体中;TEXCOORDn可自由传递任意数据(如光照向量、自定义参数)。
🎨 片元着色器输出语义
片元着色器最终输出至渲染目标:
| 语义 | 数据类型 | 描述 |
|---|---|---|
SV_Target |
fixed4/float4 |
输出颜色到帧缓存(默认渲染目标) |
SV_Targetn |
任意 |
多渲染目标(MRT)输出(n=0-7) |
示例代码:
hlsl
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
fixed4 frag(v2f i) : SV_Target {
return tex2D(_MainTex, i.uv);
}
️ 关键规则与注意事项
语义冲突规避:
- 输入/输出结构体中的
TEXCOORDn含义不同:顶点输入时由Unity自动填充纹理坐标,输出时可自定义用途; - 避免在相同结构体重复使用同一
TEXCOORDn索引。
精度控制:
- 优先用
fixed(11位)处理颜色,half(16位)处理中等范围数值,减少GPU开销。
跨管线兼容:
- URP中
POSITION与SV_POSITION需严格区分:前者为输入模型坐标,后者为输出裁剪坐标; - 内置管线
POSITION在片元输入中已被弃用,需替换为SV_POSITION
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)

本文介绍了Unity URP渲染管线中着色器的数据传递语义规范。重点讲解了顶点着色器输入(如POSITION、NORMAL等)、顶点到片元着色器的插值数据(必需SV_POSITION,可自定义TEXCOORDn)以及片元着色器输出(SV_Target)的语义定义。同时强调了语义使用中的关键规则:避免语义冲突、合理选择数值精度(fixed/half/float)、以及URP与内置管线的语义区别。通过规范化的语义定义,开发者可以正确实现着色器间的数据传递,优化渲染性能。
浙公网安备 33010602011771号