Unity Shader基础知识的学习记录,整理了一些Unity内置的变量、函数及常用的语义,HLSL的内置函数,便于快速查阅。
数据类型对应关系
ShaderLab中的属性类型和CG中变量的类型之间的匹配关系如下表:
| ShaderLab属性类型 |
CG变量类型 |
| Color, Vector |
float4, half4, fixed4 |
| Range, Float |
float, half, fixed |
| 2D |
sampler2D |
| Cube |
samplerCube |
| 3D |
sampler3D |
Unity内置变量
变换矩阵
Unity内置的变换矩阵(float4x4):
| 变量名 |
描述 |
| UNITY_MATRIX_MVP |
当前的MVP矩阵,用于将顶点/方向矢量从模型空间变换到裁剪空间 |
| UNITY_MATRIX_MV |
当前的MV矩阵,用于将顶点/方向矢量从模型空间变换到观察空间 |
| UNITY_MATRIX_V |
当前的V矩阵,用于将顶点/方向矢量从世界空间变换到观察空间 |
| UNITY_MATRIX_P |
当前的P矩阵,用于将顶点/方向矢量从观察空间变换到裁剪空间 |
| UNITY_MATRIX_VP |
当前的VP矩阵,用于将顶点/方向矢量从世界空间变换到裁剪空间 |
| UNITY_MATRIX_T_MV |
UNITY_MATRIX_MV的转置矩阵,若UNITY_MATRIX_VP为单位正交矩阵,则其转置矩阵就是其逆矩阵 |
| UNITY_MATRIX_IT_MV |
UNITY_MATRIX_MV的逆转置矩阵,用于将法线从模型空间变换到观察空间,也可以用于得到UNITY_MATRIX_MV的逆矩阵 |
| _Object2World |
当前的模型矩阵,用于将顶点/方向矢量从模型空间变换到世界空间 |
| _World2Object |
_Object2World的逆矩阵,用于将顶点/方向矢量从世界空间变换到模型空间 |
摄像机和屏幕参数
| 变量名 |
类型 |
描述 |
| _WorldSpaceCameraPos |
float3 |
该摄像机在世界空间中的位置 |
| _ProjectionParams |
float4 |
x=1.0(如正在使用一个翻转的投影矩阵进行渲染则x=-0.1),y=Near,z=Far,w=1.0+1.0/Far(Near和Far表示近、远裁剪平面到摄像机的距离) |
| _ScreenParams |
float4 |
x=width,y=height,z=1.0+1.0/width,w=1.0+1.0/height(width和height分别是该摄像机的渲染目标RenderTarget)的像素宽度和高度 |
| _ZBufferParams |
float4 |
x=1-Far/Near,y=Far/Near,z=x/Far,w=y/Far,该变量用于线性化Z缓冲中的深度值 |
| unity_Orthoparams |
float4 |
x=width,y=height,z未定义,w=1.0(如果不是正交摄像机则w=0.0)(width和height分别是该正交摄像机的像素宽度和高度 |
| unity_CameraProjection |
float4x4 |
该摄像机的投影矩阵 |
| unity_CameraInvProjection |
float4x4 |
该摄像机的投影矩阵的逆矩阵 |
| unity_CameraWorldClipPlanes[6] |
float4 |
该摄像机的6个裁剪平面在世界空间下的方程式,按照左、右、下、上、近、远裁剪平面的顺序 |
常用的包含文件
| 文件名 |
描述 |
| UnityCG.cginc |
包含了最常使用的版主函数、宏和结构体等 |
| UnityShaderVariables.cginc |
在编译Unity Shader时,会被自动包含进来。它包含了许多内置的全局变量,如UNITY_MATRIX_MVP等 |
| Lighting.cginc |
包含了各种内置的光照模型,如果编写的是Surface Shader则会自动包含进来 |
| HLSLSupport.cginc |
在编译Unity Shader时,会被自动包含进来,声明了很多用于跨平台编译的宏和定义 |
除此之外还有一些UnityStandardBRDF.cginc、UnityStandardCore.cginc等用于实现基于物理的渲染。
常用的结构体
以下是UnityCG.cginc中包含的一些常用的结构体:
| 名称 |
描述 |
包含的变量 |
| appdata_base |
可用于顶点着色器的输入 |
顶点位置、顶点法线、第一组纹理坐标 |
| appdata_tan |
可用于顶点着色器的输入 |
顶点位置、顶点切线、顶点法线、第一组纹理坐标 |
| appdata_full |
可用于顶点着色器的输入 |
顶点位置、顶点切线、顶点法线、四组(或更多的)纹理坐标 |
| app data_img |
可用于顶点着色器的输入 |
顶点位置、第一组纹理坐标 |
| v2f_img |
可用于顶点着色器的输出 |
裁剪空间中的位置、纹理坐标 |
常用的帮助函数
以下是UnityCG.cginc中包含的一些常用的帮助函数:
| 函数名 |
描述 |
| float3 WorldSpaceViewDir(float4 v) |
输入一个模型空间中的顶点位置,返回世界空间中从该点到摄像机的观察方向 |
| float3 ObjSpaceViewDir(float4 v) |
输入一个模型空间中的顶点位置,返回模型空间中从该点到摄像机的观察方向 |
| float3 WorldSpaceLightDir(float4 v) |
仅可用于向前渲染中。输入一个模型空间中的顶点位置,返回世界空间中从该点到光源的光照方向。没有被归一化 |
| float3 ObjSpaceLightDir(float4 v) |
仅可用于向前渲染中。输入一个模型空间中的顶点位置,返回模型空间中从该点到光源的光照方向。没有被归一化 |
| float3 UnityObjectToWorldNormal(float3 norm) |
把法线方向从模型空间变换到世界空间中 |
| float3 UnityObjectToWorldDir(in float3 dir) |
把方向矢量从模型空间变换到世界空间中 |
| float3 UnityWorldToObjectDir(float3 dir) |
把方向矢量从世界空间变换到模型空间中 |
常用语义
语义其实是CG/HLSL定义的赋给Shader输入和输出的字符串,用于表达这个参数的含义,告知Shader从哪里读取数据及把数据输出到哪里。
应用阶段至顶点着色器
| 语义 |
描述 |
| POSITION |
模型空间中的顶点位置,通常是float4类型 |
| NORMAL |
顶点法线,通常是float3类型 |
| TANGENT |
顶点切线,通常是float4类型 |
| TEXCOORDn |
该顶点的纹理坐标,TEXCOORD0表示第一组纹理坐标,依次类推。通常是float2或float4类型 |
| COLOR |
顶点颜色,通常是fixed4或float4类型 |
顶点着色器至片元着色器
| 语义 |
描述 |
| SV_POSITION |
裁剪空间中的顶点坐标,结构体中必须包含一个用该语义修饰的变量 |
| COLOR0 |
通常用于输出第一组顶点颜色,不是必需的 |
| COLOR1 |
通常用于输出第二组顶点颜色,不是必需的 |
| TEXCOORD0~TEXCOORD7 |
通常用于输出纹理坐标,不是必须的 |
片元着色器输出
| 语义 |
描述 |
| SV_Target |
输出值将会存储到渲染目标RenderTarget中 |
HLSL常用内置函数
以下整理了一些常用的HLSL内置函数(Intrinsic Functions):
| 函数 |
语法 |
描述 |
| abs |
abs(x) |
绝对值 |
| acos |
acos(x) |
反余弦 |
| all |
all(x) |
测试是否全部非0值 |
| any |
any(x) |
测试是否含有非0值 |
| asin |
asin(x) |
反正弦 |
| atan |
atan(x) |
反正切 |
| atan2 |
atan2(y, x) |
计算y/x的反正切值 |
| ceil |
ceil(x) |
向上取整 |
| clamp |
clamp(x, min, max) |
将x限制在[min, max]范围内 |
| clip |
clip(x) |
如果有任意元素小于0则丢弃当前片元 |
| cos |
cos(x) |
余弦值 |
| cosh |
cosh(x) |
双曲余弦值 |
| cross |
cross(x, y) |
质量叉乘积 |
| ddx |
ddx(x) |
Returns the partial derivative of x with respect to the screen-space x-coordinate. |
| ddy |
ddy(x) |
Returns the partial derivative of x with respect to the screen-space y-coordinate. |
| degrees |
degrees(x) |
弧度值转为角度值 |
| determinant |
determinant(m) |
返回矩阵(方阵)m的值 |
| distance |
distance(x, y) |
返回两点距离 |
| dot |
dot(x, y) |
矢量点乘积 |
| exp |
exp(x) |
e为底x为指数的值 |
| exp2 |
exp2(x) |
2为底x为指数的值 |
| faceforward |
faceforward(n, i, ng) |
Returns -n * sign(dot(i, ng)) |
| floor |
floor(x) |
向下取整 |
| fmod |
fmod(x, y) |
返回x/y的浮点余数 |
| frac |
frac(x) |
返回x的小数部分 |
| fwidth |
fwidth(x) |
Returns abs(ddx(x)) + abs(ddy(x)) |
| isfinite |
isfinite(x) |
x是否为有限值 |
| isinf |
isinf(x) |
x是否为无限 |
| isnan |
isnan(x) |
如果x是NAN或QNAN则返回true否则false |
| length |
length(v) |
返回矢量长度 |
| lerp |
lerp(x, y, s) |
插值,返回 x + s(y - x). |
| lit |
lit(n • l, n • h, m) |
返回光照矢量(ambient, diffuse, specular, 1) |
| log |
log(x) |
返回e为底x的对数 |
| log10 |
log10(x) |
返回10为底x的对数 |
| log2 |
log2(x) |
返回2为底x的对数 |
| max |
max(x, y) |
较大值 |
| min |
min(x, y) |
较小值 |
| modf |
modf(x, out ip) |
将x分为整数和小数部分 |
| mul |
mul(x, y) |
矩阵乘法 |
| noise |
noise(x) |
使用Perlin-noise algorithm产生一个随机值 |
| normalize |
normalize(x) |
正交化 |
| pow |
pow(x, y) |
x的y次幂 |
| radians |
radians(x) |
角度转弧度 |
| reflect |
reflect(i, n) |
返回反射矢量 |
| refract |
refract(i, n, R) |
返回折射矢量 |
| round |
round(x) |
取最近的整数 |
| rsqrt |
rsqrt(x) |
返回 1 / sqrt(x) |
| saturate |
saturate(x) |
截取x到[0, 1]范围内 |
| sign |
sign(x) |
返回x的符号 |
| sin |
sin(x) |
正弦值 |
| sincos |
sincos(x, out s, out c) |
得到x的正弦值和余弦值 |
| sinh |
sinh(x) |
双曲正弦值 |
| smoothstep |
smoothstep(min, max, x) |
Returns a smooth Hermite interpolation between 0 and 1. |
| sqrt |
sqrt(x) |
平方根 |
| step |
step(a, x) |
Returns (x >= a) ? 1 : 0 |
| tan |
tan(x) |
正切值 |
| tanh |
tanh(x) |
双曲正切值 |
| tex1D |
tex1D(s, t) |
1D纹理查询 |
| tex2D |
tex2D(s, t) |
2D纹理查询 |
| tex3D |
tex3D(s, t) |
3D纹理查询 |
| texCUBE |
texCUBE(s, t) |
Cube纹理查询 |
| transpose |
transpose(m) |
返回m的转置 |
| trunc |
trunc(x) |
将浮点数截取为整数 |
REFERENCE
《Unity Shader入门精要》
https://msdn.microsoft.com/en-us/library/ff471376.aspx