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