文章

Unity Shader 参考文档

Unity Shader 参考文档

Semantics(语义)

应用程序到顶点着色器的数据(appdata)

语义描述
float4 vertex : POSITION;顶点的本地坐标
uint vid : SV_VertexID;顶点的索引ID
float3 normal : NORMAL;顶点的法线信息
float4 tangent : TANGENT;顶点的切线信息
float4 texcoord : TEXCOORD0;顶点的UV1信息
float4 texcoord1 : TEXCOORD1;顶点的UV2信息
float4 texcoord2 : TEXCOORD2;顶点的UV3信息
float4 texcoord3 : TEXCOORD3;顶点的UV4信息
fixed4 color : COLOR;顶点的顶点色信息

顶点着色器到片断着色器的数据 (v2f)

语义描述
float4 pos:SV_POSITION;顶点的齐次裁剪空间下的坐标,默认情况下用POSITION也可以(PS4下不支持),但是为了支持所有平台,所以最好使用SV_POSITION
TEXCOORD0~N例如TEXCOORD0、TEXCOORD1、TEXCOORD2…等等
COLOR0~N例如COLOR0、COLOR1、COLOR2…等等,主要用于低精度数据,由于平台适配问题,不建议在v2f中使用COLORn
float face:VFACE如果渲染表面朝向摄像机,则Face节点输出正值1,如果远离摄像机,则输出负值-1
UNITY_VPOS_TYPE screenPos : VPOS当前片断在屏幕上的位置(单位是像素,可除以_ScreenParams.xy来做归一化),此功能仅支持#pragma target 3.0及以上编译指令
uint vid : SV_VertexID顶点着色器可以接收具有”顶点编号”作为无符号整数的变量,当需要从纹理或ComputeBuffers中获取额外的顶点数据时比较有用,此语义仅支持#pragma target 3.5及以上

注意事项:

  • OpenGL ES2.0支持最多8个
  • OpenGL ES3.0支持最多16个

片断着色器输出的数据(fragOutput)

语义描述
fixed4 color : SV_Target;默认RenderTarget,也是默认输出的屏幕上的颜色,同时支持SV_Target1、SV_Target2…等等
fixed depth : SV_Depth;通过在片断着色器中输出SV_DEPTH语义可以更改像素的深度值,注意此功能相对会消耗性能,在没有特别需求的情况下尽量不要用

Properties(属性)

基础属性类型

属性描述
_Int("Int", Int) = 1类型:整型
Cg/HLSL:int
取决于在Cg/HLSL中是用float还是int来声明的,如果定义为float则实际使用的就是浮点数,定义为int会被识别为int类型(去小数点直接取整)
_Float ("Float", Float ) = 0类型:浮点数值
Cg/HLSL:可根据需要定义不同的浮点精度
• float:32位精度,常用于世界坐标位置以及UV坐标
• half:16位精度,范围[-6W,6W],常用于本地坐标位置,方向等
• fixed:11位精度,范围[-2,2],1/265的小数精度,常用于纹理与颜色等低精度的情况
_Slider ("Slider", Range(0, 1)) = 0类型:数值滑动条
本身还是Float类型,只是通过Range(min,max)来控制滑动条的最小值与最大值
_Color("Color", Color) = (1,1,1,1)类型:颜色属性
Cg/HLSL:float4/half4/fixed4
_Vector ("Vector", Vector) = (0,0,0,0)类型:四维向量
在Properties中无法定义二维或者三维向量,只能定义四维向量

纹理属性

属性描述
_MainTex ("Texture", 2D) = "white" {}类型:2D纹理
Cg/HLSL:sampler2D/sampler2D_half/sampler2D_float
默认值有white、black、gray、bump以及空,空就是white
_MainTexArray ("TextureArray", 2DArray) = "white" {}类型:2D纹理数组
TEXTURE2D_ARRAY(_MainTexArray); SAMPLER(sampler_MainTexArray);
SAMPLE_TEXTURE2D_ARRAY(_MainTexArry, sampler_MainTexArry, i.uv,_Index);
默认值有white、black、gray、bump以及空,空就是white
仅支持DX10、OpenGL3.0、Metal及以上版本
_MainTex3D ("Texture", 3D) = "white" {}类型:3D纹理
Cg/HLSL:sampler3D/sampler3D_half/sampler3D_float
_MainCube ("Texture", Cube) = "white" {}类型:立方体纹理
Cg/HLSL:samplerCUBE/samplerCUBE_half/samplerCUBE_float
_MainTex ("Texture", Any) = "white" {}类型:通用纹理
支持2D、3D、Cube

Attributes(属性修饰符)

修饰符描述
[Header(xxx)]用于在材质面板中当前属性的上方显示标题xxx,注意只支持英文、数字、空格以及下划线
[HideInInspector]在材质面板中隐藏此条属性,在不希望暴露某条属性时可以快速将其隐藏
[Space(n)]使材质面板属性之前有间隔,n为间隔的数值大小
[HDR]标记为属性为高动态范围
[PowerSlider(3)]滑条曲率,必须加在range属性前面,用于控制滑动的数值比例
[IntRange]必须使用在Range属性之上,以使在材质面板中滑动时只能生成整数
[Toggle]开关,加在数值类型前,可使材质面板中的数值变成开关,0是关,1是开
[ToggleOff]与Toggle相当,0是开,1是关
[Enum(Off, 0, On, 1)]数值枚举,可直接在cg中使用此关键字来替代数字,最多可定义7个,超出后无法以下拉列表框的形式展现
[KeywordEnum (Enum0, Enum1, Enum2, Enum3, Enum4, Enum5, Enum6, Enum7, Enum8)]关键字枚举,需要#pragma multi_compile _XXX_ENUM0 _XXX_ENUM1 …来依次声明变体关键字,XXX为这条属性中声明的变量名,在cg/hlsl中可以通过#​if #elif #endif分别做判断
[Enum (UnityEngine.Rendering.CullMode)]内置枚举,可在Enum()内直接调用Unity内部的枚举
[NoScaleOffset]只能加在纹理属性前,使其隐藏材质面板中的Tiling和Offset
[Normal]只能加在纹理属性前,标记此纹理是用来接收法线贴图的,当用户指定了非法线的纹理时会在材质面板上进行警告提示
[Gamma]Float和Vector属性默认情况下不会进行颜色空间转换,可以通过添加[Gamma]来指明此属性为sRGB值
[PerRendererData]标记当前属性将以材质属性块的形式来自于每个渲染器数据
[MainTexture]标记当前纹理为主纹理,便于C#通过Material.mainTexture调用
[MainColor]标记当前颜色为主颜色,便于C#通过Material.color调用

Math(数学运算)

基础数学函数

函数描述
abs(x)取绝对值,即正值返回正值,负值返回的还是正值,x值也可以为向量
acos(x)反余弦函数,输入参数范围为[-1, 1],返回[0, π] 区间的弧度值
asin(x)返回x的反正弦值,范围为(-π/2,π/2)
atan(x)返回x的反正切值,范围为(-π/2,π/2),表示弧度
atan2(y,x)返回y/x的反正切值
ceil(x)对x进行向上取整,即x=0.1返回1,x=1.5返回2,x=-0.3返回0
clamp(x,a,b)如果x值小于a,则返回a;如果x值大于b,返回b;否则返回x
cos(x)返回弧度x的余弦值,范围在[-1,1]之间
cosh(x)双曲余弦函数
degrees(x)将x从弧度转换成角度
exp(x)计算e的x次方,e = 2.71828182845904523536
exp2(x)计算2的x次方
floor(x)对x值进行向下取整(去尾求整)
fmod(x,y)返回x/y的余数。如果y为0,结果不可预料,注意!如果x为负值,返回的结果也是负值!
frac(x)返回x的小数部分
log(x)返回x的自然对数
log2(x)返回以2为底的自然对数
log10(x)返回以10为底的自然对数
max(a,b)比较两个标量或等长向量元素,返回最大值
min(a,b)比较两个标量或等长向量元素,返回最小值
pow(x,y)返回x的y次方
round(x)返回x四舍五入的值
saturate(x)如果x<0返回0,如果x>1返回1,否则返回x
sin(x)返回弧度x的正弦值,范围在[-1,1]之间
sinh(x)双曲正弦函数
sqrt(x)返回x的平方根
tan(x)返回x的正切值

向量运算

函数描述  
all(a)当a或a的所有分量都为true或者非0时返回1(true),否则返回0(false)  
any(a)如果a=0或者a中的所有分量为0,则返回0(false);否则返回1(true)  
cross(a,b)返回两个三维向量a与b的叉积  
dot(a,b)点乘,a和b可以为标量也可以为向量,其计算结果是两个向量夹角的余弦值,相当于|a| *b* cos(θ)或者a.xb.x+a.yb.y+a.z*b.z
distance(a,b)返回a,b间的距离  
length(v)返回一个向量的模,即 sqrt(dot(v,v))  
normalize(v)返回一个向量的归一化版本(方向一样,但是模为1)  
reflect(I, N)根据入射光方向向量I,和顶点法向量N,计算反射光方向向量  
refract(I,N,eta)计算折射向量,I为入射光线,N为法向量,eta为折射系数  

插值和步进函数

函数描述
lerp(A,B,alpha)线性插值。如果alpha=0,则返回A;如果alpha=1,则返回B;否则返回A与B的混合值
smoothstep(min,max,x)平滑插值,如果x比min小,返回0;如果x比max大,返回1;如果x处于范围[min,max]中,则返回0和1之间的值
step(a,b)如果a<=b返回1,否则返回0

导数函数

函数描述
ddx(v)当前像素右边的v值-当前像素的v值(水平方向的差值)
ddy(v)当前像素下边的v值-当前像素的v值(垂直方向的差值)
fwidth(v)当前像素与它右边及下边像素的差值,abs(ddx(v)) + abs(ddy(v))

纹理采样

内置渲染管线

函数描述
tex1D(samper1D tex,float s)一维纹理采样
tex2D(samper2D tex,float2 s)二维纹理采样
tex2Dlod(samper2D tex,float4 s)二维纹理采样,s.w表示采样的是mipmap的几级,仅在ES3.0以上支持
tex2DProj(samper2D tex,float4 s)二维投影纹理采样,uv使用s.xy/s.w
texCUBE(samperCUBE tex,float3 s)立方体纹理采样
tex3D(samper3D tex,float3 s)3D纹理采样,uv使用xyz

URP渲染管线

函数描述
TEXTURE2D(textureName);二维纹理的定义(纹理与采样器分离定义)
TEXTURECUBE(textureName);立方体纹理的定义(纹理与采样器分离定义)
SAMPLER(samplerName);采样器的定义(纹理与采样器分离定义)
SAMPLE_TEXTURE2D(textureName, samplerName, coord);进行二维纹理采样操作
SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord,lod);进行二维纹理采样操作
SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord,bias);对mipmap进行偏移后再采样纹理
SAMPLE_TEXTURECUBE(textureName, samplerName, coord);进行立方体纹理采样操作
SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord,lod);进行立方体纹理采样操作
SAMPLE_TEXTURE3D(textureName, samplerName, coord);进行3D纹理采样操作

纹理数组采样(URP)

函数描述
TEXTURE2D_ARRAY(textureName);纹理数组的定义
SAMPLER(sampler_samplerName);纹理数组的采样器定义
SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index);纹理数组采样

常用指令

指令描述
mov dest, src1dest = src1
add dest, src1, src2dest = src1 + src2
mul dest, src1, src2dest = src1 * src2
div dest, src1, src2dest = src1 / src2
mad dest, src1, src2, src3dest = src1 * src2 + src3
dp2 dest, src1, src2(src1.x * src2.x) + (src1.y * src2.y)
dp3 dest, src1, src2(src1.x * src2.x) + (src1.y * src2.y) + (src1.z * src2.z)
dp4 dest, src1, src2(src1.x * src2.x) + (src1.y * src2.y) + (src1.z * src2.z) + (src1.w * src2.w)
rsq dest, src1rsqrt(src1) 对src1进行平方根的倒数

BuildIn Variables(内置变量)

基础函数

函数描述
UNITY_INITIALIZE_OUTPUT(type,name)由于HLSL编缉器不接受没有初始化的数据,所以为了支持所有平台,从而需要使用此方法进行初始化
TRANSFORM_TEX(i.uv,_MainTex)对UV进行Tiling与Offset变换
float3 UnityWorldSpaceLightDir( float3 worldPos )返回顶点到灯光的向量

Camera and Screen

内置渲染管线

变量描述
_WorldSpaceCameraPos主相机的世界坐标位置,类型:float3
UnityWorldSpaceViewDir(i.worldPos)世界空间下的相机方向(顶点到主相机),类型:float3
_CameraDepthTexture深度纹理,需要在脚本中开启相机的深度:Camera.main.depthTextureMode = DepthTextureMode.Depth
ComputeScreenPos(float4 pos)pos为裁剪空间下的坐标位置,返回的是某个投影点下的屏幕坐标位置
_ScreenParams屏幕的相关参数,单位为像素。x表示屏幕的宽度,y表示屏幕的高度,z表示1+1/屏幕宽度,w表示1+1/屏幕高度

URP渲染管线

变量描述
_WorldSpaceCameraPos相机在世界空间下的位置坐标(xyz)
_ZBufferParamsZ Buffer参数,包含近远裁剪面信息
_CameraDepthTexture深度纹理,在PipelineAsset中勾选DepthTexture
_CameraOpaqueTexture抓屏纹理,在PipelineAsset中勾选OpaqueTexture
_ScreenParams屏幕的相关参数,单位为像素
_ScaledScreenParams同上,但是有考虑到RenderScale的影响

Time

变量描述
_Time时间,主要用于在Shader做动画,类型:float4
x = t/20
y = t
z = t2w = t3
_SinTimet是时间的正弦值,返回值(-1~1)
x = t/8
y = t/4
z = t/2
w = t
_CosTimet是时间的余弦值,返回值(-1~1)
x = t/8
y = t/4
z = t/2
w = t
unity_DeltaTimedt是时间增量,smoothDt是平滑时间
x = dt
y = 1/dt
z = smoothDt
w = 1/smoothDt

Lighting (内置渲染管线)

变量描述
_LightColor0主平行灯的颜色值,rgb = 颜色x亮度;a = 亮度
_WorldSpaceLightPos0平行灯:(xyz=位置,z=0),已归一化
其它类型灯:(xyz=位置,z=1)
unity_WorldToLight从世界空间转换到灯光空间下,等同于旧版的_LightMatrix0

Fog and Ambient (内置渲染管线)

变量描述
unity_AmbientSky环境光(Gradient)中的Sky Color
unity_AmbientEquator环境光(Gradient)中的Equator Color
unity_AmbientGround环境光(Gradient)中的Ground Color
UNITY_LIGHTMODEL_AMBIENT环境光(Color)中的颜色,等同于环境光(Gradient)中的Sky Color

GPU Instancing

内容描述
实现步骤用于对多个对象(网格一样,材质一样,但是材质属性不一样)合批,单个合批最大上限为511个对象
1. #pragma multi_compile_instancing 添加此指令后会使材质面板上曝露Instaning开关
2. UNITY_VERTEX_INPUT_INSTANCE_ID 在顶点着色器的输入(appdata)和输出(v2f可选)中添加(uint instanceID : SV_InstanceID)
3. 构建需要实例化的额外数据
4. UNITY_SETUP_INSTANCE_ID(v) 放在顶点着色器/片断着色器(可选)中最开始的地方
5. UNITY_TRANSFER_INSTANCE_ID(v, o) 当需要将实例化ID传到片断着色器时,在顶点着色器中添加
6. UNITY_ACCESS_INSTANCED_PROP(arrayName, propName) 在片断着色器中访问具体的实例化变量
Instancing选项对GPU Instancing进行一些设置
• #pragma instancing_options forcemaxcount:batchSize 强制设置单个批次内Instancing的最大数量
• #pragma instancing_options maxcount:batchSize 设置单个批次内Instancing的最大数量

BuildIn Transformation(内置变换)

空间变换(矩阵)

内置渲染管线

矩阵描述
UNITY_MATRIX_MVP模型空间»投影空间
UNITY_MATRIX_MV模型空间»观察空间
UNITY_MATRIX_V视图空间
UNITY_MATRIX_P投影空间
UNITY_MATRIX_VP视图空间>投影空间
unity_ObjectToWorld本地空间»世界空间
unity_WorldToObject世界空间>本地空间

URP渲染管线

函数描述
GetObjectToWorldMatrix()本地空间到世界空间的矩阵
GetWorldToObjectMatrix()世界空间到本地空间的矩阵
GetWorldToViewMatrix()世界空间到观察空间的矩阵
GetWorldToHClipMatrix()世界空间到齐次裁剪空间的矩阵
GetViewToHClipMatrix()观察空间到齐次裁剪空间的矩阵

空间变换(方法)

内置渲染管线

函数描述
UnityObjectToClipPos(v.vertex)将模型空间下的顶点转换到齐次裁剪空间
UnityObjectToWorldNormal(v.normal)将模型空间下的法线转换到世界空间(已归一化)
UnityObjectToWorldDir (v.tangent)将模型空间下的切线转换到世界空间(已归一化)
UnityWorldSpaceLightDir (i.worldPos)世界空间下顶点到灯光方向的向量(未归一化)
UnityWorldSpaceViewDir (i.worldPos)世界空间下顶点到视线方向的向量(未归一化)

URP渲染管线

函数描述
float3 TransformObjectToWorld (float3 positionOS)从本地空间变换到世界空间
float3 TransformWorldToObject (float3 positionWS)从世界空间变换到本地空间
float3 TransformWorldToView(float3 positionWS)从世界空间变换到视图空间
float4 TransformObjectToHClip(float3 positionOS)将模型空间下的顶点变换到齐次裁剪空间
float4 TransformWorldToHClip(float3 positionWS)将世界空间下的顶点变换到齐次裁剪空间
float4 TransformWViewToHClip (float3 positionVS)将视图空间下的顶点变换到齐次裁剪空间
float3 TransformObjectToWorldNormal (float3 normalOS)将法线从本地空间变换到世界空间(已归一化)

基础变换矩阵

矩阵类型矩阵定义
平移矩阵```float4x4 M_translate = float4x4(
1, 0, 0, T.x,
0, 1, 0, T.y,
0, 0, 1, T.z,
0, 0
本文由作者按照 CC BY 4.0 进行授权