Unity的包含文件

目录

包含文件的使用语法

UnityCG.cginc

1.顶点着色器输入结构体

2.顶点变换函数

3.向量变换函数

4.灯光辅助函数

5.视角向量函数

6.其他辅助函数和宏

UnityShaderVariables.cginc

1.空间变换矩阵

2.时间变量

使用包含文件简化Shader


包含文件的使用语法

包含文件是以cginc作为扩展名的文本文件

文件所在路径:

Unity安装目录/Editor/Data/CGIncludes/

在编写Shader时,只需要使用编译指令提前把对应的文件包进Shader,就可以直接使用了。

包含文件的声明也要写在CG代码块内,它的语法结构:

{

CGPROGRAM

//......

#include"UnityCG.cginc"

//......

ENDCG

}

只要输入了正确的文件名称,Shader在编译的时候就会自动在这个路径下寻找对应的文件。

UnityCG.cginc

1.顶点着色器输入结构体

2.顶点变换函数

|---------------------------------------------|---------------------|---------------------------------------|
| 函数 | 说明 | 等同于 |
| float4 UnityObjectToClipPos(float3 pos) | 模型空间------>齐次裁剪空间 | mul(UNITY_MATRIX_MVP,float4(pos,1,0)) |
| float3 UnityObjectToViewPos(float3 pos) | 模型空间------>摄像机空间 | mul(UNITY_MATRIX_MV,float4(pos,1,0)) |
| float4 UnityWorldToViewPos(float3 pos) | 世界空间------>摄像机空间 | mul(UNITY_MATRIX_V,float4(pos,1,0)) |
| float3 UnityWorldToClipPos(float3 pos) | 世界空间------>齐次裁切空间 | mul(UNITY_MATRIX_VP,float4(pos,1,0)) |
| float4 UnityViewToClipPos(float3 pos) | 摄像机空间------>齐次裁切空间 | mul(UNITY_MATRIX_P,float4(pos,1,0)) |

3.向量变换函数

|--------------------------------------------------|---------------------|
| 函数 | 说明(已经标准化处理) |
| float4 UnityObjectToWorldDir(float3 dir) | 向量:模型空间------>世界空间 |
| float4 UnityWorldToObjectDir(float3 dir) | 向量:世界空间------>模型空间 |
| float4 UnityObjectToWorldNormal(float3 norm) | 法线:模型空间------>世界空间 |

4.灯光辅助函数

定义了一些计算顶点指向灯光的方向向量

|----------------------------------------------------|-------------------------------------------------|
| float3 UnityWorldSpaceLightDir(in float3 worldPos) | 输入世界空间顶点坐标,返回世界空间中从顶点指向灯光的向量 |
| float3 ObjSpaceLightDir(in float4 v) | 输入模型空间顶点坐标,返回模型空间中从顶点指向灯光的向量 |
| float3 Shade4PointLights(...) | 输入一系列所需变量,返回4个点光源的光照信息,在前向渲染中使用这个函数计算逐顶点的光照 |

5.视角向量函数

|-----------------------------------------|----------------------------------|
| 函数 | 说明(没有被标准化) |
| float3 UnityWorldSpaceViewDir(float3 v) | 输入世界空间顶点坐标,返回世界空间中从顶点指向灯光的向量 |
| float3 ObjSpaceViewDir(float4 pos) | 输入模型空间顶点,返回模型空间中从顶点指向摄像机的向量 |

6.其他辅助函数和宏

|------------------------------------------|--------------------------------------|
| 函数 | 说明 |
| TRANSFORM_TEX(tex,name) | 宏定义,输入UV坐标和纹理名称,得到贴图和纹理坐标 |
| fixed3 UnpackNormal(fixed4 packednormal) | 将法线向量从[0,1]映射到[-1,1] |
| half Luminance(half3 rgb) | 将颜色数据转变为灰度数据 |
| float4 ComputeScreenPos(float4 pos) | 输入裁切空间顶点坐标,**得到屏幕空间纹理坐标,**用于屏幕空间纹理映射 |
| float4 ComputeGrabScreenPos(float4 pos) | 输入裁切空间顶点坐标,得到采样GrabPass的纹理坐标 |

宏定义的语法结构为:

#define name string;

1)#define:表示宏定义的指令

2)name:宏名称,后续可以直接输入名称进行使用

3)string:"在编译前,预处理器会将代码中所有'宏名称',原封不动地替换成它后面定义的'内容'。"

UnityShaderVariables.cginc

1.空间变换矩阵

可以直接使用CG函数mul(Matrix,Vertex)将顶点在不同空间之间进行变换

矩阵名称 类型 变换方向 核心用途 适用场景
UNITY_MATRIX_M float4x4 模型空间 → 世界空间 顶点 / 向量从模型空间转世界空间 计算世界空间顶点位置、世界空间法线
UNITY_MATRIX_V float4x4 世界空间 → 视图空间 顶点 / 向量从世界空间转摄像机本地(视图)空间 计算视图空间视角向量、视图空间光照
UNITY_MATRIX_P float4x4 视图空间 → 裁剪空间 顶点从视图空间转裁剪空间(最终输出) 顶点着色器最终输出 SV_POSITION
UNITY_MATRIX_MV float4x4 模型空间 → 视图空间 等价于 UNITY_MATRIX_V * UNITY_MATRIX_M 快速计算视图空间顶点位置(减少矩阵乘法)
UNITY_MATRIX_MVP float4x4 模型空间 → 裁剪空间 等价于 UNITY_MATRIX_P * UNITY_MATRIX_MV 顶点着色器直接输出裁剪空间位置(最常用)
UNITY_MATRIX_T_MV float4x4 视图空间 → 模型空间(转置) 向量从视图空间转模型空间(仅方向向量) 视图空间方向向量转回模型空间
UNITY_MATRIX_IT_MV float4x4 视图空间 → 模型空间(逆转置) 法向量从视图空间转模型空间(保证垂直性) 法向量的空间变换(避免拉伸)
_World2Object float4x4 世界空间 → 模型空间 等价于 UNITY_MATRIX_M 的逆矩阵 世界空间向量转回模型空间
_Object2World float4x4 模型空间 → 世界空间 UNITY_MATRIX_M 完全等价(别名) 习惯用 _Object2World 的开发者兼容

2.时间变量

在实现动态效果的时候经常会使用时间因子作为动态变量,是实现 Shader 动效(如流光、溶解、呼吸灯)的核心基础。

所有时间变量均为 float/float4 类型,单位为秒(s),从游戏启动时开始计时(暂停时停止)。

变量名称 类型 核心含义 常用场景
_Time float4 (t/20, t, t*2, t*3),其中 t = 游戏运行总时间 多倍速时间控制(慢速 / 常规 / 快速动效)
_SinTime float4 (sin(t/8), sin(t/4), sin(t/2), sin(t))t = 游戏运行总时间 周期性平滑动效(呼吸、摇摆、淡入淡出)
_CosTime float4 (cos(t/8), cos(t/4), cos(t/2), cos(t))t = 游戏运行总时间 _SinTime 配合实现相位偏移的周期动效
unity_DeltaTime float4 (dt, 1/dt, smoothDt, 1/smoothDt),其中 dt = 帧间隔时间 帧率无关的动效(避免动效速度随帧率变化)
_AnimationTime float (Unity 2019+)动画时间(针对 SkinnedMeshRenderer),范围通常 0~1 顶点动画、骨骼动画联动的 Shader 效果

1. 最常用:_Time(线性时间)

_Time 是基础时间变量,四个分量对应不同速度的时间流逝,可直接用于线性动效:

  • _Time.x = 总时间 / 20 → 超慢速(适合缓慢位移、渐变)
  • _Time.y = 总时间 → 常规速度(默认首选)
  • _Time.z = 总时间 × 2 → 2 倍速
  • _Time.w = 总时间 × 3 → 3 倍速

示例:UV 滚动(流光 / 流水效果)

// 片元着色器中实现纹理UV水平滚动

fixed4 frag (v2f i) : SV_Target

{

// 基础UV + 时间偏移(_Time.y是常规速度,乘以滚动速度系数_ScrollSpeed)

float2 uv = i.uv + float2(_ScrollSpeed * _Time.y, 0);

fixed4 col = tex2D(_MainTex, uv);

return col;

}

2. 周期动效:_SinTime / _CosTime(正弦 / 余弦时间)

正弦 / 余弦函数的取值范围是 [-1, 1],适合实现 "往复循环" 的动效(如呼吸、缩放、摇摆),通常会先映射到 [0, 1] 区间使用:

  • _SinTime.x = sin (t/8) → 周期 16π ≈ 50 秒(超慢呼吸)
  • _SinTime.y = sin (t/4) → 周期 8π ≈ 25 秒
  • _SinTime.z = sin (t/2) → 周期 4π ≈ 12 秒
  • _SinTime.w = sin (t) → 周期 2π ≈ 6 秒

示例:呼吸灯效果(亮度随时间变化)

fixed4 frag (v2f i) : SV_Target

{

// 1. 获取正弦值(范围[-1,1])

float sinVal = _SinTime.w;

// 2. 映射到[0,1]区间(呼吸的亮度范围)

float brightness = (sinVal + 1.0) * 0.5;

// 3. 基础颜色 × 亮度(可叠加强度系数_BrightnessScale)

fixed4 col = tex2D(_MainTex, i.uv) * brightness * _BrightnessScale;

return col;

}

3. 帧率无关:unity_DeltaTime(帧时间)

直接用 _Time 可能因帧率波动导致动效速度不稳定,unity_DeltaTime 可实现帧率无关的动效:

  • unity_DeltaTime.x = 本次帧间隔时间(dt)
  • unity_DeltaTime.y = 1/dt(慎用,帧率低时数值会很大)
  • unity_DeltaTime.z = 平滑后的 dt(推荐,避免帧率突变)

示例:帧率无关的顶点位移

v2f vert (appdata v)

{

v2f o;

// 顶点基础位置 + 随时间的位移(乘以平滑帧时间,保证不同帧率下速度一致)

v.vertex.y += _MoveSpeed * unity_DeltaTime.z;

o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

o.uv = v.uv;

return o;

}

溶解效果(时间驱动的 Alpha 裁剪)

fixed4 frag (v2f i) : SV_Target

{

fixed4 col = tex2D(_MainTex, i.uv);

// 1. 噪声纹理(溶解边缘的随机效果)

fixed noise = tex2D(_NoiseTex, i.uv).r;

// 2. 时间驱动的溶解阈值(0~1,从无到有溶解)

float dissolveThreshold = _Time.y * _DissolveSpeed;

// 3. 裁剪像素(噪声值 < 阈值则透明)

clip(noise - dissolveThreshold);

// 4. 溶解边缘加红边

if (noise - dissolveThreshold < 0.1)

{ col.r = 1.0; }

return col;

}

避坑关键点

  1. 时间范围与映射
    • _SinTime/_CosTime 的原始值是 [-1,1],如需 0~1 的范围,用 (val + 1.0) * 0.5 映射;
    • 如需自定义周期,不要依赖内置的 _SinTime.x/y/z/w,而是自己计算:sin(_Time.y * _CustomSpeed)_CustomSpeed 是自定义速度系数)。
  2. 性能注意事项
    • 避免在片元着色器中重复计算复杂的时间函数(如多次计算 sin(_Time.y)),可在顶点着色器中计算后插值传入;
    • unity_DeltaTime.y(1/dt)在帧率极低时会趋近于无穷大,慎用,优先用 unity_DeltaTime.z(平滑 dt)。
  3. 暂停处理
    • Unity 的时间变量默认受 Time.timeScale 影响(暂停时 timeScale=0,时间停止);
    • 如需不受暂停影响的时间,用 _Time 不如自己在 C# 中传 Time.realtimeSinceStartup 到 Shader(自定义 uniform 变量)。

使用包含文件简化Shader

核心功能是给模型渲染一张纹理贴图,并叠加自定义主颜色。

顶点着色器的作用:处理每个顶点的位置、纹理坐标等数据,传递给片元着色器。

  • v2f_img vert(appdata_img v)
    • appdata_imgUnityCG.cginc 内置的顶点输入结构体 ,包含 vertex(顶点位置)、texcoord(纹理坐标)等基础数据(无需自己定义结构体)。
    • v2f_imgUnityCG.cginc 内置的顶点输出 / 片元输入结构体 ,包含 pos(裁剪空间位置)、uv(纹理坐标)。
  • o.pos=UnityObjectToClipPos(v.vertex);
    • UnityObjectToClipPos:Unity 内置宏(替代 mul(UNITY_MATRIX_MVP, v.vertex)),将模型空间顶点 转换为裁剪空间顶点(显卡最终渲染的位置)。
  • o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
    • TRANSFORM_TEXUnityCG.cginc 内置宏,计算纹理的最终 UV 坐标(叠加 Tiling/Offset),等价于:
    • o.uv = v.texcoord * _MainTex_ST.xy + _MainTex_ST.zw;
    • 作用:让你在 Unity 面板调整纹理的 Tiling(缩放)和 Offset(偏移)时,UV 坐标同步变化。

片元着色器(frag 函数)

fixed4 frag(v2f_img i):SV_TARGET { return tex2D(_MainTex,i.uv)*_MainColor; }

片元着色器的作用:处理每个像素(片元)的颜色,是最终渲染效果的核心。

  • fixed4 frag(v2f_img i):SV_TARGET
    • i:接收顶点着色器传递过来的 v2f_img 数据(包含 posuv)。
    • :SV_TARGET:声明函数返回值是渲染目标(即最终输出到屏幕的像素颜色)。
  • tex2D(_MainTex,i.uv):采样纹理 _MainTexi.uv 坐标处的颜色(tex2D 是 2D 纹理采样函数)。
  • *_MainColor:将采样得到的纹理颜色与主颜色相乘(叠加色调)。
  • return:返回最终的像素颜色。
相关推荐
mxwin3 小时前
Unity Shader 实战屏幕颜色抓取实现径向模糊 (URP)
unity·游戏引擎·shader·uv
林枫依依7 小时前
Unity2017 项目源码打开即崩溃,无法打开的解决办法
unity
wearegogog1237 小时前
ESP32迷你无人机开发代码详解
游戏引擎·无人机·cocos2d
心前阳光9 小时前
Unity使用豆包语音模型
unity·游戏引擎
张老师带你学9 小时前
unity资源:星际飞船 陨石 虫族 星球
科技·游戏·unity·模型·游戏美术
心前阳光9 小时前
Unity使用豆包语言模型
unity·语言模型
魔士于安9 小时前
unity宇宙飞船
游戏·unity·游戏引擎·贴图·模型
RReality10 小时前
【Unity Shader】高级光照与阴影总结:渲染路径、多光源、透明阴影
unity·游戏引擎
浪客川10 小时前
godot-rust入门案例
rust·游戏引擎·godot