Unity Shader 超常用魔法目录

Unity Shader速写金手指,从古至今,讳莫如深!绝赞收集中

内置包含文件

Unity中有类似于C++的包含文件.cginc,在编写Shader时我们可以使用#include指令把这些文件包含进来
这样我们就可以使用Unity为我们提供的一些非常好用的函数、宏和变量。

例如:#include"UnityCG.cginc"

包含文件的位置:根目录\Editor\Data\CGIncludes

Unity中常用包含文件

  • UnityCG.cginc: 包含最常用的帮助函数、宏和结构体
  • UnityShaderVariables.cginc: 在编译Shader时,会被自动包含进来,包含了许多内置的全局变量,如UNITY_MATRIX_MVP
  • Ligghting.cginc: 包含了各种内置光照模型,如果编写SurfaceShader的话,会被自动包含进来
  • HLSLSurport.cginc: 在编译Shader时,会被自动包含进来,声明了很多跨平台编译的宏和定义

UnityShader中常用的结构体

Struct Name Discription Included Arguments
appdata_base vert input float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
appdata_tan vert input float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
appdata_full vert input float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
float4 texcoord3 : TEXCOORD3;
#if defined(SHADER_API_XBOX360)
half4 texcoord4 : TEXCOORD4;
half4 texcoord5 : TEXCOORD5;
#endif
fixed4 color : COLOR;
appdata_img vert input float4 vertex : POSITION;
half2 texcoord : TEXCOORD0;
v2f_img vert output float4 pos : SV_POSITION;//裁剪空间中的位置
half2 uv : TEXCOORD0;

常用函数

Function Discription
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) 把方向矢量从世界空间转换到模型空间

内置变量

Variable Discription
UNITY_MATRIX_MVP 当前模型观察投影矩阵,用于将模型顶点/方向矢量从模型空间转换到裁剪空间
UNITY_MATRIX_MV 当前模型观察矩阵,用于将模型顶点/方向矢量从模型空间转换到观察空间
UNITY_MATRIX_V 当前观察矩阵,用于将顶点/方向矢量从世界空间变换到观察空间
UNITY_MATRIX_P 当前投影矩阵,用于将顶点/方向矢量从观察空间变换到裁剪空间
UNITY_MATRIX_VP 当前观察投影矩阵,用于将顶点/方向矢量从世界空间变换到裁剪空间
UNITY_MATRIX_T_MV UNITY_MATRIX_MV转置矩阵
UNITY_MATRIX_IT_MV UNITY_MATRIX_MV逆转置矩阵,可将法线矢量从模型空间转换到观察空间
_Object2World 当前模型的矩阵,用于将模型顶点/方向矢量从模型空间转换到世界空间
_World2Object _Object2World逆矩阵,用于将模型顶点/方向矢量从世界空间转换到模型空间

另:Unity还提供了能够访问时间、光照、雾效和环境光等目的的变量。这些内置变量大多在UnityShaderVariables.cginc中,跟光照有关的还定义在Lighting.cgincAutoLight.cginc中。

Misc

  1. uint CreateShader(enum type) : 创建空的shader object;
    type: VERTEX_SHADER,
  2. void ShaderSource(uint shader, sizeicount, const **string, const int *length):加载shader源码进shader object;可能多个字符串
  3. void CompileShader(uint shader):编译shader object;
    shader object有状态 表示编译结果
  4. void DeleteShader( uint shader ):删除 shader object;
  5. void ShaderBinary( sizei count, const uint *shaders, enum binaryformat, const void *binary, sizei length ): 加载预编译过的shader 二进制串;
  6. uint CreateProgram( void ):创建空的program object, programe object组织多个shader object,成为executable;
  7. void AttachShader( uint program, uint shader ):关联shader object和program object;
  8. void DetachShader( uint program, uint shader ):解除关联;
  9. void LinkProgram( uint program ):program object准备执行,其关联的shader object必须编译正确且符合限制条件;
  10. void UseProgram( uint program ):执行program object;
  11. void ProgramParameteri( uint program, enum pname, int value ): 设置program object的参数;
  12. void DeleteProgram( uint program ):删除program object;
  13. shader变量的qualifier:
    默认:无修饰符,普通变量读写, 与外界无连接;
    const:常量 const vec3 zAxis = vec3(0.0, 0.0, 1.0);
    attribute: 申明传给vertex shader的变量;只读;不能为array或struct;attribute vec4 position;
    uniform: 表明整个图元处理中值相同;只读; uniform vec4 lightPos;
    varying: 被差值;读写; varying vec3 normal;
    in, out, inout;

变量精度:

  • highp
  • mediump
  • lowp

SL内置变量:

  • gl_Position: 用于vertex shader, 写顶点位置;被图元收集、裁剪等固定操作功能所使用;
    其内部声明是:highp vec4 gl_Position;

  • gl_PointSize: 用于vertex shader, 写光栅化后的点大小,像素个数;
    其内部声明是:mediump float gl_Position;

  • gl_FragColor: 用于Fragment shader,写fragment color;被后续的固定管线使用;
    mediump vec4 gl_FragColor;

  • gl_FragData: 用于Fragment shader,是个数组,写gl_FragData[n] 为data n;被后续的固定管线使用;mediump vec4 gl_FragData[gl_MaxDrawBuffers];

    gl_FragColor和gl_FragData是互斥的,不会同时写入;

  • gl_FragCoord: 用于Fragment shader,只读, Fragment相对于窗口的坐标位置 x,y,z,1/w; 这个是固定管线图元差值后产生的;z 是深度值; mediump vec4 gl_FragCoord;

  • gl_FrontFacing: 用于判断 fragment是否属于 front-facing primitive;只读;

  • gl_PointCoord: 仅用于 point primitive; mediump vec2 gl_PointCoord;

SL内置常量

1
2
3
4
5
6
7
8
const mediump int gl_MaxVertexAttribs = 8; 
const mediump int gl_MaxVertexUniformVectors = 128;
const mediump int gl_MaxVaryingVectors = 8;
const mediump int gl_MaxVertexTextureImageUnits = 0;
const mediump int gl_MaxCombinedTextureImageUnits = 8;
const mediump int gl_MaxTextureImageUnits = 8;
const mediump int gl_MaxFragmentUnitformVectors = 16;
const mediump int gl_MaxDrawBuffers = 1;

SL内置数学函数

一般默认都用弧度
radians(degree): 角度变弧度;
degrees(radian): 弧度变角度;
sin(angle), cos(angle), tan(angle);
asin(x): arc sine, 返回弧度 [-PI/2, PI/2];
acos(x): arc cosine,返回弧度 [0, PI];
atan(y, x): arc tangent, 返回弧度 [-PI, PI];
atan(y/x): arc tangent, 返回弧度 [-PI/2, PI/2];

pow(x, y): x的y次方;
exp(x): 指数, log(x);
exp2(x): 2的x次方, log2(x);
sqrt(x): x的根号; inversesqrt(x): x根号的倒数;

abs(x): 绝对值;
sign(x): 符号, 1, 0 或 -1;

sign(x)或者Sign(x)叫做符号函数,在数学和计算机运算中,其功能是取某个数的符号(正或负:
当x>0,sign(x)=1,
当x=0,sign(x)=0,
当x<0, sign(x)=-1;
floor(x): 底部取整;
ceil(x): 顶部取整;
fract(x): 取小数部分;
mod(x, y): 取模, x - y*floor(x/y)
min(x, y): 取最小值;
max(x, y): 取最大值;
clamp(x, min, max): min(max(x, min), max);
mix(x, y, a): x, y的线性混叠, x(1-a) + y*a
step(edge, x);
smoothstep(edge0, edge1, x): threshod smooth transition时使用:
edge0<=edge0时为0.0, x>=edge1时为1.0;

length(x): 向量长度;
distance(p0, p1): 两点距离, length(p0-p1)
dot(x, y): 点积,各分量分别相乘 后 相加;
cross(x, y): 差积,x[1]*y[2]-y[1]*x[2], x[2]*y[0] - y[2]*x[0], x[0]*y[1] - y[0]*x[1]
normalize(x): 归一化, length(x)=1;
faceforward(N, I, Nref): 若dot(Nref, I)< 0则N, 否则 -N;
reflect(I, N): I的反射方向, I -2*dot(N, I)*N, N必须先归一化;
refract(I, N, eta): 折射,k=1.0-eta*eta*(1.0 - dot(N, I) * dot(N, I))
若k<0.0则0.0,否则 eta*I - (eta*dot(N, I)+sqrt(k))*N

matrixCompMult(matX, matY): 矩阵相乘, 每个分量 自行相乘, 即r*[j] = x[j]*y[j];
矩阵线性相乘,直接用*

lessThan(vecX, vecY): 向量 每个分量比较 x < y;
lessThanEqual(vecX, vecY): 向量 每个分量比较 x<=y;
greaterThan(vecX, vecY): 向量 每个分量比较 x>y;
greaterThanEqual(vecX, vecY): 向量 每个分量比较 x>=y;
equal(vecX, vecY): 向量 每个分量比较 x==y;
notEqual(vecX, vexY): 向量 每个分量比较 x!=y;
any(bvecX): 只要有一个分量是true, 则true;
all(bvecX): 所有分量是true, 则true;
not(bvecX): 所有分量取反;

texture2D(sampler2D, coord): texture lookup;
texture2D(sampler2D, coord, bias): LOD bias, mip-mapped texture;
texture2DProj(sampler2D, coord);
texture2DProj(sampler2D, coord, bias);
texture2DLod(sampler2D, coord, lod);
texture2DProjLod(sampler2D, coord, lod);
textureCube(samplerCube, coord);
textureCube(samplerCube, coord, bias);
textureCubeLod(samplerCube, coord, lod)。

Share