文章

Unity Shader 参考文档 - 第三部分

Unity Shader 参考文档 - 第三部分

Pragma(编译指令)

基础编译指令

指令描述
​#pragma target 2.0​Shader编绎目标级别,默认值为2.5
• 2.0: 基础功能
• 2.5: derivatives
• 3.0: 2.5 + interpolators10 + samplelod + fragcoord
• 3.5: 3.0 + interpolators15 + mrt4 + integers + 2darray + instancing
• 4.0: 3.5 + geometry
• 4.5: 3.5 + compute + randomwrite
• 4.6: 4.0 + cubearray + tesshw + tessellation
• 5.0: 4.0 + compute + randomwrite + tesshw + tessellation
​#pragma require xxx​表明shader需要的特性功能
• interpolators10: 至少支持10个插值器
• interpolators15: 至少支持15个插值器
• interpolators32: 至少支持32个插值器
• mrt4: 至少支持4个Multiple Render Targets
• mrt8: 至少支持8个Multiple Render Targets
• derivatives: 片断着色器支持偏导函数(ddx/ddy)
• samplelod: 纹理LOD采样
• fragcoord: 将像素的位置传入到片断着色器中
• integers: 支持真正的整数类型
• 2darray: 2D纹理数组
• cubearray: Cubemap纹理数组
• instancing: GPU实例化
• geometry: 几何着色器
• compute: Compute Shader
• randomwrite: 可以编写任意位置的一些纹理和缓冲区
​#pragma shader_feature​变体声明,常用于不需要程序控制开关的关键字,在编缉器的材质上设置,打包时会自动过滤
​#pragma shader_feature_local​声明本地变体(shader_feature),unity2019才支持的功能,每个Shader最多可以有64个本地变体
​#pragma multi_compile​变体声明,在打包时会把所有变体都打包进去,这是它与feature的区别
​#pragma multi_compile_local​声明本地变体(multi_compile),unity2019才支持的功能
​#pragma multi_compile_fog​雾类型定义:FOG_EXP FOG_EXP2 FOG_LINEAR
​#pragma skip_variants XXX01 XXX02...​剔除指定的变体,可同时剔除多个

内置渲染管线特定指令

指令描述
​#pragma multi_compile_fwdbase​定义在LightMode = ForwardBase的Pass中,生成Unity在ForwardBase中需要的各种内置宏
​#pragma multi_compile_fwdadd​定义在LightMode=ForwardAdd的Pass中,生成Unity在ForwardAdd中需要的各种内置宏
​#pragma multi_compile_shadowcaster​定义在LightMode=ShadowCaster的Pass中,会自动生成SHADOWS_DEPTH和SHADOW_CUBE宏

URP特定指令

指令描述
​#pragma prefer_hlslcc gles​将HLSL代码转换为GLSL代码时,优先使用HLSLcc转换器
​#include "XXX.hlsl"​引入hlsl文件
​#include_with_pragmas "XXX.hlsl"​引入hlsl文件,同时也会使用hlsl文件中的#pragma指令
​#pragma editor_sync_compilation​强制某个Shader以同步的方式进行编绎

平台相关指令

指令描述
​#pragma only_renderers​仅编译指定平台的Shader
• d3d11 - Direct3D 11/12
• glcore - OpenGL 3.x/4.x
• gles - OpenGL ES 2.0
• gles3 - OpenGL ES 3.x
• metal - iOS/Mac Metal
• vulkan - Vulkan
• d3d11_9x - Direct3D 11 9.x功能级别
• xboxone - Xbox One
• ps4 - PlayStation 4
• psp2 - PlayStation Vita
• n3ds - Nintendo 3DS
• wiiu - Nintendo Wii U
​#pragma exclude_renderers​剔除掉指定平台的相关代码
​#pragma once​通常添加在通用的.hlsl文件中,以此来避免多次或者重复引用和编绎

其他指令

指令描述
​#define NAME​定义一个叫NAME的字段
​#define NAME 1​定义一个叫NAME的字段并且它的值为1
​#error xxx​多用于分支的判断中,利用此语句可直接输出一条报错信息
​#pragma fragmentoption ARB_precision_hint_fastest​最快的,意思就是会用低精度
​#pragma fragmentoption ARB_precision_hint_nicest​最佳的,会用高精度
​#pragma enable_d3d11_debug_symbols​开启调试,便于在调试工具中进行查看分析
​#pragma skip_optimizations <gles/vulkan...>​调试用,禁用某平台的优化
​#pragma shader_feature EDITOR_VISUALIZATION​开启Material Validation,Scene视图中的模式

Render State(渲染状态)

Cull(背面剔除)

1
Cull Back | Front | Off
  • Back: 表示剔除背面,也就是显示正面,这也是最常用的设置
  • Front: 表示剔除前面,只显示背面
  • Off: 表示关闭剔除,也就是正反面都渲染

模版测试(Stencil)

1
2
3
4
5
6
7
8
9
10
Stencil
{
    Ref [_Stencil]
    ReadMask [_StencilReadMask]
    WriteMask [_StencilWriteMask]
    Comp [_StencilComp]
    Pass [_StencilOp]
    Fail [_Fail]
    ZFail [_ZFail]
}

Comp(比较操作)

操作描述
​Less​相当于”<”操作,即仅当左边<右边,模板测试通过,渲染像素
​Greater​相当于”>”操作,即仅当左边>右边,模板测试通过,渲染像素
​Lequal​相当于”<=”操作,即仅当左边<=右边,模板测试通过,渲染像素
​Gequal​相当于”>=”操作,即仅当左边>=右边,模板测试通过,渲染像素
​Equal​相当于”=”操作,即仅当左边=右边,模板测试通过,渲染像素
​NotEqual​相当于”!=”操作,即仅当左边!=右边,模板测试通过,渲染像素
​Always​不管公式两边为何值,模板测试总是通过,渲染像素
​Never​不管公式两边为何值,模板测试总是失败,像素被抛弃

模版缓冲区的更新

操作描述
​Keep​保留当前缓冲中的内容,即stencilBufferValue不变
​Zero​将0写入缓冲,即stencilBufferValue值变为0
​Replace​将参考值写入缓冲,即将referenceValue赋值给stencilBufferValue
​IncrSat​将当前模板缓冲值加1,如果stencilBufferValue超过255了,那么保留为255
​DecrSat​将当前模板缓冲值减1,如果stencilBufferValue超过为0,那么保留为0
​Invert​将当前模板缓冲值(stencilBufferValue)按位取反
​IncrWrap​当前缓冲的值加1,如果缓冲值超过255了,那么变成0
​DecrWrap​当前缓冲的值减1,如果缓冲值已经为0,那么变成255

深度缓冲

|设置|描述| | ————–| ———————————————————————————————| |ZTest (Less|Greater| |​ZTest[unity_GUIZTestMode]​|unity_GUIZTestMode用于UI材质中,此值默认为LEqual,仅当UI中Canvas模式为Overlay时,值为Always| |ZWrite On|Off| |ZClip True|False| |​Offset Factor, Units`​|深度偏移,offset = (m * factor) + (r * units),默认值为0,0|

颜色遮罩

1
ColorMask RGB | A | 0 | R、G、B、A的任意组合

颜色遮罩,默认值为:RGBA,表示写入RGBA四个通道。

混合(Blend)

1
源颜色*SrcFactor + 目标颜色*DstFactor

混合因子

因子描述
​One​源或目标的完整值
​Zero​0
​SrcColor​源的颜色值
​SrcAlpha​源的Alpha值
​DstColor​目标的颜色值
​DstAlpha​目标的Alpha值
​OneMinusSrcColor​1-源颜色得到的值
​OneMinusSrcAlpha​1-源Alpha得到的值
​OneMinusDstColor​1-目标颜色得到的值
​OneMinusDstAlpha​1-目标Alpha得到的值

常用的几种混合类型

1
2
3
4
5
6
Blend SrcAlpha OneMinusSrcAlpha  // Traditional transparency
Blend One OneMinusSrcAlpha       // Premultiplied transparency
Blend One One                     // Additive
Blend OneMinusDstColor One       // Soft Additive
Blend DstColor Zero              // Multiplicative
Blend DstColor SrcColor          // 2x Multiplicative

混合操作的具体运算符

操作描述
​Add​源+目标
​Sub​源-目标
​RevSub​目标-源
​Min​源与目标中最小值
​Max​源与目标中最大值

其他

设置描述
AlphaToMask On|Off 
Conservative True|False 

Transformation(空间变换)

空间变换(矩阵)

矩阵描述
​UNITY_MATRIX_M​模型变换矩阵:unity_ObjectToWorld
​UNITY_MATRIX_I_M​模型变换逆矩阵:unity_WorldToObject
​UNITY_MATRIX_V​视图变换矩阵:unity_MatrixV
​UNITY_MATRIX_I_V​视图变换逆矩阵:unity_MatrixInvV
​UNITY_MATRIX_P​投影变换矩阵:OptimizeProjectionMatrix(glstate_matrix_projection)
​UNITY_MATRIX_I_P​投影变换逆矩阵:ERROR_UNITY_MATRIX_I_P_IS_NOT_DEFINED
​UNITY_MATRIX_VP​视图投影变换矩阵:unity_MatrixVP
​UNITY_MATRIX_I_VP​视图投影变换逆矩阵:_InvCameraViewProj
​UNITY_MATRIX_MV​模型视图变换矩阵:mul(UNITY_MATRIX_V, UNITY_MATRIX_M)
​UNITY_MATRIX_T_MV​模型视图变换转置矩阵:transpose(UNITY_MATRIX_MV)
​UNITY_MATRIX_IT_MV​模型视图变换转置逆矩阵:transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V))
​UNITY_MATRIX_MVP​模型视图投影变换矩阵:mul(UNITY_MATRIX_VP, UNITY_MATRIX_M)

空间变换(方法)

内置渲染管线

函数描述
​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)​模型空间»齐次裁剪空间 (比MVP高效)
​float4 TransformWorldToHClip(float3 positionWS)​世界空间»齐次裁剪空间
​float4 TransformWViewToHClip(float3 positionVS)​视图空间»齐次裁剪空间
​real3 TransformObjectToWorldDir(real3 dirOS)​(向量)模型空间»世界空间
​real3 TransformWorldToObjectDir(real3 dirWS)​(向量)世界空间»模型空间
​real3 TransformWorldToViewDir(real3 dirWS)​(向量)世界空间»视图空间
​real3 TransformWorldToHClipDir(real3 directionWS)​(向量)世界空间>齐次裁剪空间
​float3 TransformObjectToWorldNormal(float3 normalOS)​(法线)模型空间»世界空间(已归一化)
​float3 TransformWorldToObjectNormal(float3 normalWS)​(法线)世界空间»模型空间(已归一化)

基础变换矩阵

矩阵类型矩阵定义
平移矩阵​float4x4 M_translate = float4x4( 1, 0, 0, T.x, 0, 1, 0, T.y, 0, 0, 1, T.z, 0, 0, 0, 1);​
缩放矩阵​float4x4 M_scale = float4x4( S.x, 0, 0, 0, 0, S.y, 0, 0, 0, 0, S.z, 0, 0, 0, 0, 1);​
旋转矩阵(X轴)​float4x4 M_rotationX = float4x4( 1, 0, 0, 0, 0, cos(θ), -sin(θ), 0, 0, sin(θ), cos(θ), 0, 0, 0, 0, 1);​
旋转矩阵(Y轴)​float4x4 M_rotationY = float4x4( cos(θ), 0, sin(θ), 0, 0, 1, 0, 0, -sin(θ), 0, cos(θ), 0, 0, 0, 0, 1);​
旋转矩阵(Z轴)​float4x4 M_rotationZ = float4x4( cos(θ), -sin(θ), 0, 0, sin(θ), cos(θ), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);​

变换规则

1
2
3
4
将P点从A空间变换到B空间
P_B = M_AB * P_A
     = (M_BA)^-1 * P_A
     = (M_BA)^T * P_A

Predefined Macros(预定义宏)

Target platform

宏描述
​SHADER_API_D3D11​Direct3D 11
​SHADER_API_GLCORE​桌面OpenGL核心(GL3/4)
​SHADER_API_GLES​OpenGl ES 2.0
​SHADER_API_GLES3​OpenGl ES 3.0/3.1
​SHADER_API_METAL​IOS/Mac Metal
​SHADER_API_VULKAN​Vulkan
​SHADER_API_D3D11_9X​Direct3D 11 9.x功能级别
​SHADER_API_PS4​PS4平台,SHADER_API_PSSL同时也会被定义
​SHADER_API_XBOXONE​Xbox One
​SHADER_API_MOBILE​所有移动平台(GLES/GLES3/METAL)
​SHADER_API_DESKTOP​Window、Mac和Linux桌面平台

流程控制

宏描述
​#define UNITY_BRANCH [branch]​添加在if语句上面,表示此语句会根据判断只执行符合条件的代码,有跳转指令
​#define UNITY_FLATTEN [flatten]​添加在if语句上面,表示此语句会执行全部代码,然后根据条件来选择某个具体的结果,没有跳转指令
​#define UNITY_UNROLL [unroll]​添加在for语句上面,表示此循环在编绎时会展开所有循环代码
​#define UNITY_UNROLLX(_x) [unroll(_x)]​添加在for语句上面,功能同上,同时可以指定具体的展开次数
​#define UNITY_LOOP [loop]​添加在for语句上面,表示此循环不可展开,正常执行跳转

Shader target model

宏描述
​#if SHADER_TARGET < 30​对应于#pragma target的值,2.0就是20,3.0就是30

Unity version

宏描述
​#if UNITY_VERSION >= 500​Unity版本号判断,500表示5.0.0

Platform difference helpers

宏描述
​UNITY_UV_STARTS_AT_TOP​一般此判断当前平台是DX(UV原点在左上角)还是OpenGL(UV原点在左下角)
​UNITY_NO_SCREENSPACE_SHADOWS​定义移动平台不进行Cascaded ScreenSpace Shadow

UI

宏描述
​UNITY_UI_CLIP_RECT​当父级物体有Rect Mask 2D组件时激活
需要先手动定义此变体#pragma multi_compile _ UNITY_UI_CLIP_RECT
同时需要声明:_ClipRect(一个四维向量)
UnityGet2DClipping (float2 position, float4 clipRect)即可实现遮罩

Lighting

宏描述
​UNITY_SHOULD_SAMPLE_SH​是否进行计算SH(光照探针与顶点着色)
​UNITY_SAMPLE_FULL_SH_PER_PIXEL​光照贴图uv和来自SHL2的环境颜色在顶点和像素内插器中共享
​HANDLE_SHADOWS_BLENDING_IN_GI​当同时定义了SHADOWS_SCREEN与LIGHTMAP_ON时开启
​UNITY_SHADOW_COORDS(N)​定义一个float4类型的变量_ShadowCoord,语义为第N个TEXCOORD
​V2F_SHADOW_CASTER;​用于”LightMode” = “ShadowCaster”中,相当于定义了float4 pos:SV_POSITION

Other

宏描述
​UNITY_SHADER_NO_UPGRADE​另Shader不自动更新API,只需把语句用注释的形式写在shader中任意位置即可

URP特定宏

宏描述
​UNITY_NO_DXT5nm​法线纹理是否不采用DXT5压缩,移动平台是,非移动平台否
​UNITY_ASTC_NORMALMAP_ENCODING​当在移动平台中,法线纹理采用类DXT5nm的压缩时启用
​SHADERGRAPH_PREVIEW​在ShaderGraph中的Custom Function自义定节点上使用,用于判断是否处于SG面板预览中
本文由作者按照 CC BY 4.0 进行授权