Lv.1 Unity主线:Unity函数常用速查

常用

最常用的函数

排名 函数 用途 频率
1 UnityObjectToClipPos 顶点变换 ⭐⭐⭐⭐⭐
2 UnityObjectToWorldNormal 法线变换 ⭐⭐⭐⭐⭐
3 UnityObjectToWorldDIr 切线变换 ⭐⭐⭐⭐⭐
4 normalize 向量归一化 ⭐⭐⭐⭐⭐
5 dot 点积(光照) ⭐⭐⭐⭐⭐
6 tex2D 纹理采样 ⭐⭐⭐⭐⭐
7 UnityWorldSpaceLightDir 光照方向 ⭐⭐⭐⭐
8 UnityWorldSpaceViewDir 视线方向 ⭐⭐⭐⭐
9 mul(unity_ObjectToWorld, v.vertex) 世界坐标 ⭐⭐⭐⭐
10 lerp 插值混合 ⭐⭐⭐⭐
11 saturate 限制[0,1] ⭐⭐⭐
12 TRANSFORM_TEX(v.texcoord, _MainTex) UV控制 ⭐⭐⭐⭐⭐
13 clip(); 裁剪 ⭐⭐⭐⭐

最常用的5个矩阵

排名 矩阵 变换 频率
1 unity_ObjectToWorld 模型→世界 ⭐⭐⭐⭐⭐
2 UNITY_MATRIX_MVP 模型→裁剪 ⭐⭐⭐⭐
3 UNITY_MATRIX_V 世界→视图 ⭐⭐⭐
4 UNITY_MATRIX_P 视图→裁剪 ⭐⭐⭐
5 UNITY_MATRIX_VP 世界→裁剪 ⭐⭐⭐

全部

一、Unity坐标空间变换函数总表

位置变换函数

函数名 输入 输出 说明 示例
UnityObjectToClipPos 模型空间位置 裁剪空间位置 最常用,模型→裁剪 float4 clipPos = UnityObjectToClipPos(v.vertex);
UnityObjectToViewPos 模型空间位置 视图空间位置 模型→视图 float3 viewPos = UnityObjectToViewPos(v.vertex);
UnityWorldToViewPos 世界空间位置 视图空间位置 世界→视图 float3 viewPos = UnityWorldToViewPos(worldPos);
UnityWorldToClipPos 世界空间位置 裁剪空间位置 世界→裁剪 float4 clipPos = UnityWorldToClipPos(worldPos);
mul(unity_ObjectToWorld, v.vertex) 模型空间位置 世界空间位置 模型→世界(手动) float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

方向/法线变换函数

函数名 输入 输出 说明 示例
UnityObjectToWorldNormal 模型空间法线 世界空间法线 自动处理转置逆 float3 worldNormal = UnityObjectToWorldNormal(v.normal);
UnityObjectToWorldDir 模型空间方向 世界空间方向 方向向量变换 float3 worldDir = UnityObjectToWorldDir(v.tangent.xyz);
UnityWorldToObjectDir 世界空间方向 模型空间方向 反向变换 float3 objDir = UnityWorldToObjectDir(lightDir);

光照相关函数

函数名 输入 输出 说明 示例
UnityWorldSpaceLightDir 世界空间位置 光源方向(世界空间) 自动处理点光源/方向光 float3 lightDir = UnityWorldSpaceLightDir(worldPos);
ObjSpaceLightDir 模型空间位置 光源方向(模型空间) 模型空间光照 float3 lightDir = ObjSpaceLightDir(v.vertex);
UnityWorldSpaceViewDir 世界空间位置 视线方向(世界空间) 从顶点指向相机 float3 viewDir = UnityWorldSpaceViewDir(worldPos);
ObjSpaceViewDir 模型空间位置 视线方向(模型空间) 模型空间视线 float3 viewDir = ObjSpaceViewDir(v.vertex);

屏幕空间相关函数

函数名 输入 输出 说明 示例
ComputeScreenPos 裁剪空间位置 屏幕空间位置 用于屏幕特效 float4 screenPos = ComputeScreenPos(clipPos);
ComputeGrabScreenPos 裁剪空间位置 抓取屏幕位置 用于折射等效果 float4 grabPos = ComputeGrabScreenPos(clipPos);

深度相关函数

函数名 输入 输出 说明 示例
COMPUTE_EYEDEPTH SV_POSITION 线性眼空间深度 计算深度值 COMPUTE_EYEDEPTH(o.depth);
DECODE_EYEDEPTH 深度纹理值 线性眼空间深度 解码深度 float depth = DECODE_EYEDEPTH(depthTex);
Linear01Depth 深度缓冲值 [0,1]线性深度 深度值线性化 float depth = Linear01Depth(depthValue);
LinearEyeDepth 深度缓冲值 眼空间线性深度 实际距离 float depth = LinearEyeDepth(depthValue);

二、Unity变换矩阵总表

基础变换矩阵

矩阵名 类型 变换 说明 使用示例
unity_ObjectToWorld float4x4 模型→世界 M矩阵 float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
unity_WorldToObject float4x4 世界→模型 M逆矩阵 float3 objPos = mul(unity_WorldToObject, worldPos).xyz;
UNITY_MATRIX_V float4x4 世界→视图 V矩阵(视图矩阵) float3 viewPos = mul(UNITY_MATRIX_V, worldPos).xyz;
UNITY_MATRIX_I_V float4x4 视图→世界 V逆矩阵 float3 worldPos = mul(UNITY_MATRIX_I_V, viewPos).xyz;
UNITY_MATRIX_P float4x4 视图→裁剪 P矩阵(投影矩阵) float4 clipPos = mul(UNITY_MATRIX_P, viewPos);

组合变换矩阵

矩阵名 类型 变换 等价于 使用示例
UNITY_MATRIX_VP float4x4 世界→裁剪 P × V float4 clipPos = mul(UNITY_MATRIX_VP, worldPos);
UNITY_MATRIX_MVP float4x4 模型→裁剪 P × V × M float4 clipPos = mul(UNITY_MATRIX_MVP, v.vertex);
UNITY_MATRIX_MV float4x4 模型→视图 V × M float3 viewPos = mul(UNITY_MATRIX_MV, v.vertex).xyz;
UNITY_MATRIX_IT_MV float4x4 法线变换(模型→视图) (MV)^-T(转置逆) float3 viewNormal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);

特殊矩阵

矩阵名 类型 说明 使用场景
unity_MatrixInvP float4x4 投影矩阵的逆 深度重建世界坐标
unity_MatrixInvVP float4x4 VP矩阵的逆 屏幕坐标→世界坐标
unity_WorldToCamera float4x4 世界→相机矩阵 等同于UNITY_MATRIX_V
unity_CameraToWorld float4x4 相机→世界矩阵 等同于UNITY_MATRIX_I_V

三、空间变换流程对照表

完整变换链

空间 坐标范围 如何到达 常用矩阵/函数 用途
模型空间 物体局部坐标 从Mesh读取 v.vertex 顶点动画、物体局部效果
  M矩阵 unity_ObjectToWorld  
世界空间 场景全局坐标 mul(unity_ObjectToWorld, v.vertex) UnityObjectToWorldNormal 光照计算、物体交互
  V矩阵 UNITY_MATRIX_V  
视图空间 相机为原点 mul(UNITY_MATRIX_V, worldPos) UnityWorldToViewPos 雾效、深度计算
  P矩阵 UNITY_MATRIX_P  
裁剪空间 (x,y,z,w) UnityObjectToClipPos(v.vertex) UNITY_MATRIX_MVP 输出到SV_POSITION
  透视除法 硬件自动  
NDC空间 [-1,1]或[0,1] /w(硬件) - 归一化坐标
  视口变换 硬件自动  
屏幕空间 像素坐标 ComputeScreenPos - 屏幕特效、UI

四、常用变换组合速查表

位置变换快速查询

从 → 到 方法1(函数) 方法2(矩阵) 推荐
模型 → 世界 - mul(unity_ObjectToWorld, v.vertex).xyz 矩阵
模型 → 视图 UnityObjectToViewPos(v.vertex) mul(UNITY_MATRIX_MV, v.vertex).xyz 函数
模型 → 裁剪 UnityObjectToClipPos(v.vertex) mul(UNITY_MATRIX_MVP, v.vertex) 函数⭐
世界 → 视图 UnityWorldToViewPos(worldPos) mul(UNITY_MATRIX_V, float4(worldPos, 1)).xyz 函数
世界 → 裁剪 UnityWorldToClipPos(worldPos) mul(UNITY_MATRIX_VP, float4(worldPos, 1)) 函数
视图 → 裁剪 - mul(UNITY_MATRIX_P, float4(viewPos, 1)) 矩阵

法线/方向变换快速查询

从 → 到 方法1(函数) 方法2(矩阵) 推荐 注意事项
模型法线 → 世界 UnityObjectToWorldNormal(v.normal) mul((float3x3)unity_WorldToObject, v.normal) 函数⭐ 自动转置逆
模型方向 → 世界 UnityObjectToWorldDir(v.tangent.xyz) mul((float3x3)unity_ObjectToWorld, dir) 函数 不需要转置逆
世界方向 → 模型 UnityWorldToObjectDir(worldDir) mul((float3x3)unity_WorldToObject, dir) 函数 -

五、光照计算常用函数表

光照方向获取

函数 输入空间 输出 光源类型支持 说明
UnityWorldSpaceLightDir(worldPos) 世界空间位置 世界空间光源方向 方向光、点光源、聚光灯 自动处理衰减
ObjSpaceLightDir(v.vertex) 模型空间位置 模型空间光源方向 方向光、点光源、聚光灯 模型空间光照
_WorldSpaceLightPos0 - 世界空间光源位置/方向 主光源 方向光时为方向向量

视线方向获取

函数 输入空间 输出 说明
UnityWorldSpaceViewDir(worldPos) 世界空间位置 世界空间视线方向 从顶点指向相机
ObjSpaceViewDir(v.vertex) 模型空间位置 模型空间视线方向 模型空间视线
_WorldSpaceCameraPos - 世界空间相机位置 相机位置

光照颜色/属性

变量名 类型 说明 使用场景
_LightColor0 fixed4 主光源颜色 前向渲染
UNITY_LIGHTMODEL_AMBIENT fixed4 环境光颜色 所有管线
unity_SHAr, unity_SHAg, unity_SHAb float4 球谐光照 间接光照

六、纹理采样相关函数表

基础采样函数

函数 说明 Shader Model要求 示例
tex2D(sampler, uv) 2D纹理采样 2.0+ fixed4 col = tex2D(_MainTex, i.uv);
tex2Dlod(sampler, float4(uv, 0, mip)) 指定mipmap层级 3.0+ fixed4 col = tex2Dlod(_MainTex, float4(i.uv, 0, 0));
tex2Dproj(sampler, float4) 投影纹理采样 2.0+ fixed4 col = tex2Dproj(_MainTex, screenPos);
tex2Dbias(sampler, float4(uv, 0, bias)) 带偏移的采样 2.0+ fixed4 col = tex2Dbias(_MainTex, float4(i.uv, 0, -1));

纹理采样(URP/HDRP)

函数 说明 示例
SAMPLE_TEXTURE2D(tex, sampler, uv) URP/HDRP标准采样 SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
SAMPLE_TEXTURE2D_LOD(tex, sampler, uv, lod) 指定LOD SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, i.uv, 0);
SAMPLE_DEPTH_TEXTURE(tex, sampler, uv) 深度纹理采样 SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, i.uv);

衍生指令(需要3.0+)

函数 说明 用途 示例
ddx(x) x对屏幕X的偏导 计算变化率 float dUdx = ddx(i.uv.x);
ddy(y) y对屏幕Y的偏导 计算变化率 float dUdy = ddy(i.uv.y);
fwidth(x) abs(ddx(x)) + abs(ddy(x)) 边缘检测 float edge = fwidth(i.uv);

七、数学函数速查表

常用数学函数

函数 说明 范围 示例
dot(a, b) 点积 [-1, 1](归一化向量) float ndotl = dot(normal, lightDir);
cross(a, b) 叉积 垂直向量 float3 binormal = cross(normal, tangent);
normalize(v) 归一化 长度=1 float3 normal = normalize(i.worldNormal);
length(v) 向量长度 >= 0 float dist = length(worldPos - _WorldSpaceCameraPos);
distance(a, b) 两点距离 >= 0 float dist = distance(worldPos, lightPos);
reflect(i, n) 反射向量 - float3 reflectDir = reflect(-viewDir, normal);
refract(i, n, eta) 折射向量 - float3 refractDir = refract(-viewDir, normal, 1.0/1.33);
lerp(a, b, t) 线性插值 - fixed3 color = lerp(shadowColor, litColor, ndotl);
smoothstep(min, max, x) 平滑插值 [0, 1] float smooth = smoothstep(0.4, 0.6, ndotl);
step(edge, x) 阶梯函数 0或1 float toon = step(0.5, ndotl);
saturate(x) 限制到[0,1] [0, 1] float val = saturate(ndotl);
clamp(x, min, max) 限制范围 [min, max] float val = clamp(ndotl, 0.2, 0.8);
pow(x, y) x的y次方 - float spec = pow(ndoth, _Gloss);
exp(x) e^x - float fog = exp(-depth * density);
log(x) ln(x) - -
sqrt(x) 平方根 - float dist = sqrt(x*x + y*y);
abs(x) 绝对值 >= 0 float val = abs(x);
sign(x) 符号 -1, 0, 1 float s = sign(x);
floor(x) 向下取整 - float stepped = floor(x * 5) / 5;
ceil(x) 向上取整 - float stepped = ceil(x * 5) / 5;
frac(x) 小数部分 [0, 1) float f = frac(x);
fmod(x, y) x % y - float m = fmod(x, 2.0);

三角函数

函数 说明 输入单位 范围
sin(x) 正弦 弧度 [-1, 1]
cos(x) 余弦 弧度 [-1, 1]
tan(x) 正切 弧度 (-∞, +∞)
asin(x) 反正弦 - [-π/2, π/2]
acos(x) 反余弦 - [0, π]
atan(x) 反正切 - [-π/2, π/2]
atan2(y, x) 两参数反正切 - [-π, π]

八、语义(Semantics)速查表

顶点着色器输入语义

语义 类型 说明 来源
POSITION float4 顶点位置(模型空间) Mesh
NORMAL float3 法线(模型空间) Mesh
TANGENT float4 切线(模型空间,w=±1) Mesh
TEXCOORD0-7 float2/4 UV坐标 Mesh
COLOR fixed4 顶点颜色 Mesh
SV_VertexID uint 顶点索引 系统自动
SV_InstanceID uint 实例索引(GPU Instancing) 系统自动

顶点着色器输出/片元着色器输入语义

语义 类型 说明 必须
SV_POSITION float4 裁剪空间位置 ✅必须
TEXCOORD0-9 float1-4 任意插值数据 可选
COLOR0-1 fixed4 颜色数据 可选
SV_IsFrontFace bool 是否正面(片元输入) 可选

完整的顶点输入语义列表:

语义 含义 数据类型
POSITION 顶点位置(模型空间) float4
NORMAL 法线(模型空间) float3
TANGENT 切线(模型空间) float4
TEXCOORD0 第一套UV float2/float4
TEXCOORD1 第二套UV(光照贴图) float2/float4
TEXCOORD2 第三套UV float2/float4
TEXCOORD3 第四套UV float2/float4
COLOR 顶点颜色 float4
SV_VertexID 顶点ID uint
SV_InstanceID 实例ID(GPU Instancing) uint

片元着色器输出语义

语义 类型 说明 用途
SV_Target fixed4 渲染目标0 输出颜色(单目标)
SV_Target0-7 fixed4 渲染目标0-7 MRT(多目标)
SV_Depth float 自定义深度 深度输出

常用系统值语义

语义 使用位置 含义
SV_POSITION 顶点输出 裁剪空间位置
SV_Target 片元输出 渲染目标
SV_Depth 片元输出 深度值
SV_VertexID 顶点输入 顶点索引
SV_InstanceID 顶点输入 实例索引
SV_PrimitiveID 几何/片元输入 图元ID
SV_IsFrontFace 片元输入 是否正面
SV_RenderTargetArrayIndex 几何输出 渲染目标数组索引

示例1:SV_VertexID(顶点ID)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct appdata
{
    float4 vertex : POSITION;
    uint vertexID : SV_VertexID;  // 顶点索引
};

v2f vert(appdata v)
{
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    
    // 使用顶点ID生成渐变色
    float t = (float)v.vertexID / 100.0;
    o.color = float4(t, 1-t, 0, 1);
    
    return o;
}

示例2:SV_IsFrontFace(正反面检测)

1
2
3
4
5
6
7
8
fixed4 frag(v2f i, bool isFrontFace : SV_IsFrontFace) : SV_Target
{
    // 正面显示红色,背面显示蓝色
    if (isFrontFace)
        return fixed4(1, 0, 0, 1);  // 红色
    else
        return fixed4(0, 0, 1, 1);  // 蓝色
}

示例3:SV_PrimitiveID(三角形ID)

1
2
3
4
5
6
fixed4 frag(v2f i, uint primitiveID : SV_PrimitiveID) : SV_Target
{
    // 每个三角形不同颜色
    float hue = frac((float)primitiveID * 0.618);
    return fixed4(hue, 1-hue, 0.5, 1);
}

示例4:SV_Depth(自定义深度)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct fragOutput
{
    fixed4 color : SV_Target;
    float depth : SV_Depth;
};

fragOutput frag(v2f i)
{
    fragOutput o;
    
    o.color = tex2D(_MainTex, i.uv);
    
    // 强制深度为0.5(总在中间)
    o.depth = 0.5;
    
    return o;
}

九、渲染状态关键字表

剔除模式

关键字 说明
Cull Back 剔除背面(默认)
Cull Front 剔除正面
Cull Off 双面渲染

深度测试

关键字 说明
ZTest Less 深度小于通过(默认)
ZTest LEqual 深度小于等于通过
ZTest Greater 深度大于通过
ZTest GEqual 深度大于等于通过
ZTest Equal 深度等于通过
ZTest NotEqual 深度不等于通过
ZTest Always 总是通过
ZTest Never 总不通过

深度写入

关键字 说明
ZWrite On 写入深度(默认)
ZWrite Off 不写入深度(透明物体)

混合模式

关键字 效果 用途
Blend Off 无混合(默认) 不透明物体
Blend SrcAlpha OneMinusSrcAlpha 标准透明 透明物体
Blend One One 加法混合 发光、粒子
Blend OneMinusDstColor One 柔和叠加 特效
Blend DstColor Zero 乘法混合 阴影、滤镜

Shader基本模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
Shader "Tutorial/CompleteReference"
{
    Properties
    {
        _MainTex ("Albedo", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
    }
    
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        
        Pass
        {
            Tags { "LightMode"="ForwardBase" }
            
            Cull Back       // 剔除背面
            ZWrite On       // 写入深度
            ZTest LEqual    // 深度测试
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase
            #pragma target 3.0
            
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Color;
            
            // ===========================================
            // 顶点着色器输入
            // ===========================================
            struct appdata
            {
                float4 vertex : POSITION;     // 模型空间位置
                float3 normal : NORMAL;       // 模型空间法线
                float4 tangent : TANGENT;     // 模型空间切线
                float2 uv : TEXCOORD0;        // UV0
                float2 uv2 : TEXCOORD1;       // UV1(光照贴图)
                fixed4 color : COLOR;         // 顶点颜色
            };
            
            // ===========================================
            // 顶点到片元
            // ===========================================
            struct v2f
            {
                float4 pos : SV_POSITION;     // 裁剪空间位置(必须)
                float2 uv : TEXCOORD0;        // UV
                float3 worldPos : TEXCOORD1;  // 世界空间位置
                float3 worldNormal : TEXCOORD2; // 世界空间法线
                float3 worldTangent : TEXCOORD3; // 世界空间切线
                float3 worldBinormal : TEXCOORD4; // 世界空间副法线
            };
            
            // ===========================================
            // 顶点着色器
            // ===========================================
            v2f vert(appdata v)
            {
                v2f o;
                
                // 位置变换
                o.pos = UnityObjectToClipPos(v.vertex);           // 模型→裁剪
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; // 模型→世界
                
                // 法线变换
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
                o.worldBinormal = cross(o.worldNormal, o.worldTangent) * v.tangent.w;
                
                // UV变换
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                
                return o;
            }
            
            // ===========================================
            // 片元着色器
            // ===========================================
            fixed4 frag(v2f i) : SV_Target
            {
                // 归一化插值后的向量
                float3 worldNormal = normalize(i.worldNormal);
                
                // 光照方向(世界空间)
                float3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
                
                // 视线方向(世界空间)
                float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
                
                // 漫反射
                float ndotl = max(0, dot(worldNormal, worldLightDir));
                
                // 采样纹理
                fixed4 albedo = tex2D(_MainTex, i.uv) * _Color;
                
                // 最终颜色
                fixed3 diffuse = _LightColor0.rgb * albedo.rgb * ndotl;
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo.rgb;
                
                return fixed4(ambient + diffuse, 1.0);
            }
            ENDCG
        }
    }
    
    FallBack "Diffuse"
}



    Enjoy Reading This Article?

    Here are some more articles you might like to read next:

  • URP - RendererFeature :ScreenSpaceOutline
  • 平滑法线处理 - 八面体映射
  • Lv.3 Unity主线:一个简单的PBRShader
  • 理论支线:直接光漫反射与GGX高光的混合问题
  • 理论支线:PBR - 基于图像的照明( image based lighting-IBL)
  • # #