一个通道 (Pass) 可以定义一个名称 (Name) 和任意数量的标签 (Tags)。这些名称/值字符串用于将通道的意图传达给渲染引擎。
示例:
Shader "Name"
{
//着色器属性
Properties
{
_WaveScale ("Wave scale", Range(0.02, 0.15)) = 0.07 // 滑动条
_RefrColor ("Refraction color", Color) = (.34, .85, .92, 1) // 颜色
}
SubShader
{
//Tags
Tags { "Queue" = "Transparent" "IgnoreProjector" = "true" "RenderType" = "Transparent" "PreviewType" = "Plane" "CanUseSpriteAtlas" = "True" }
//渲染状态设置
ZWrite Off Blend SrcAlpha OneMinusSrcAlpha Cull Off
//其他
GrabPass
{
"_RefractionTex"
}
// 子着色器中的单个通道
Pass
{
//Pass Name
Name: "MyPassName"
//Pass Tags
Tags { "LightModel" = "ForwardBase" }
// 渲染状态设置
Material
{
Diffuse [_Color]
}
Lighting On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
ENDCG
}
}
FallBack "Diffuse"
}
SubShader Tags
Queue
渲染顺序,指定该物体属于哪一个渲染队列。内建值包括:
- Background=1000
背景,一般天空盒之类的使用这个标签,最早被渲染
- Geometry=2000(默认)
适用于大部分不透明的物体
- AlphaTest=2450
如果Shader要使用AlphaTest功能 使用这个队列性能更高
- Transparent=3000
这个渲染队列在AlphaTest之后,Shader中有用到Alpha Blend的,或者深入不写入的都应该放在这个队列。
- Overlay=4000
最后渲染的队列,全屏幕后期的 都应该使用这个
可以自定义值例如"Queue"=“3100”
也支持这样的写法"Queue"=“Transparent+100”
RenderType
渲染类型,对着色器进行分类。内建值包括:
- Opaque:不透明(法线、自发光、反射、地形Shader)
- Transparent:半透明(透明、粒子、字体、地形添加通道Shader)
- TransparentCutout:遮罩透明(透明裁切、双通道植物Shader)
- Background:天空盒
- Shader Overlay:GUI纹理、光晕、闪光
- Shader TreeOpaque:地形引擎——树皮
- TreeTransparentCutout:地形引擎——树叶
- TreeBillboard:地形引擎——公告牌(始终面向摄像机)式树木
- Grass:地形引擎——草
- GrassBillboard:地形引擎——公告牌(始终面向摄像机)式草
DisableBatching
是否禁用Unity批处理功能Batch(打包、合并),可用值:
- True:禁用
- False:不禁用(默认)
- LODFading:当LOD fade开启的时候禁用,一般用在树木上面
ForceNoShadowCasting
是否强制不投射阴影,当这个值为True的时候,使用这个Shader的对象便不会投射阴影。 一般用于透明对象,或者不想继承其他shader阴影的时候。
IgnoreProjector
无视投影器,当这个值为True的时候,对象便不受投射器(Projector)影响。 一般用于半透明对象,因为让投射器影响它们不是什么好事情。
CanUseSpriteAtlas
可否使用精灵集(Sprite),当这个值为False的时候,不能使用精灵集。
PreviewType
材质的预览形式,默认显示为球体,可以使用Plane(2D平面)或Skybox(天空盒)
渲染状态设置
渲染状态设置 一个通道将设置图形硬件的各种状态,例如是否应开启 Alpha 混合或是否应使用深度测试。
命令如下所示:
Cull
Cull Back | Front | Off
- Back 不渲染背离观察者的多边形_(默认值)_。
- Front 不渲染面向观察者的多边形。用于从里到外翻转对象。
- Off 禁用剔除 - 绘制所有面。用于特殊效果。
设置多边形剔除模式。
ZTest
ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)
设置深度缓冲区测试模式。
ZWrite
ZWrite On | Off
控制是否将此对象的像素写入深度缓冲区(默认值为 On)。如果要绘制实体对象,请将其保留为 on。如果要绘制半透明效果,请切换到 ZWrite Off
。
Offset
Offset OffsetFactor, OffsetUnits
允许使用两个参数指定深度偏移:factor 和 units。Factor 相对于多边形的 X 或 Y 缩放最大 Z 斜率,而 units 缩放最小可分辨深度缓冲区值。因此可强制将一个多边形绘制在另一个多边形上,尽管它们实际上位于相同位置。例如,Offset 0, -1
将多边形拉近摄像机并忽略多边形的斜率,而 Offset -1, -1
在观察掠射角时进一步拉近多边形。
Blend
常见的混合类型
Blend SrcAlpha OneMinusSrcAlpha // 传统透明度
Blend One OneMinusSrcAlpha // 预乘透明度
Blend One One // 加法
Blend OneMinusDstColor One // 软加法
Blend DstColor Zero // 乘法
Blend DstColor SrcColor // 2x 乘法
语法
Blend Off
:关闭混合(这是默认值)
Blend SrcFactor DstFactor
:配置并启用混合。生成的颜色将乘以 SrcFactor。屏幕上的已有颜色乘以 DstFactor,然后将这两个值相加。
Blend SrcFactor DstFactor, SrcFactorA DstFactorA
:同上,但使用不同系数来混合 Alpha 通道。
BlendOp Op
:不将混合颜色相加,而是对它们执行不同的操作。
BlendOp OpColor, OpAlpha
:同上,但是对颜色 (RGB) 通道和 Alpha (A) 通道使用不同的混合操作。
此外,您还可以设置上层渲染目标混合模式。当 使用多渲染目标 (MRT) 渲染时,上面的常规语法 将为所有渲染目标设置相同的混合模式。以下语法可以为各个渲染目标设置不同的混合模式,其中 N
是渲染目标索引(0 到 7)。此功能适用于大多数现代 API/GPU(DX11/12、GLCore、Metal 和 PS4):
Blend N SrcFactor DstFactor
Blend N SrcFactor DstFactor, SrcFactorA DstFactorA
BlendOp N Op
BlendOp N OpColor, OpAlpha
AlphaToMask On
:开启 alpha-to-coverage。使用 MSAA 时,alpha-to-coverage 会根据像素着色器结果 Alpha 值按比例修改多重采样覆盖率遮罩。这通常用于比常规 Alpha 测试更少锯齿的轮廓;对植被和其他经过 Alpha 测试的着色器非常有用。
混合运算
可使用以下混合运算:
Add | 将源和目标相加。 |
Sub | 从源减去目标。 |
RevSub | 从目标减去源。 |
Min | 使用源和目标中的较小者。 |
Max | 使用源和目标中的较大者。 |
LogicalClear | 逻辑运算:清除 (0) 仅限 DX11.1。 |
LogicalSet | 逻辑运算:设置 (1) 仅限 DX11.1。 |
LogicalCopy | 逻辑运算:复制 (s) 仅限 DX11.1。 |
LogicalCopyInverted | 逻辑运算:逆复制 (!s) 仅限 DX11.1。 |
LogicalNoop | 逻辑运算:空操作 (d) 仅限 DX11.1。 |
LogicalInvert | 逻辑运算:逆运算 (!d) 仅限 DX11.1。 |
LogicalAnd | 逻辑运算:与 (s & d) 仅限 DX11.1。 |
LogicalNand | 逻辑运算:与非 !(s & d) 仅限 DX11.1。 |
LogicalOr | Logical operation: Or (s | d) DX11.1 only. |
LogicalNor | Logical operation: Nor !(s | d) DX11.1 only. |
LogicalXor | 逻辑运算:异或 (s ^ d) 仅限 DX11.1。 |
LogicalEquiv | 逻辑运算:相等 !(s ^ d) 仅限 DX11.1。 |
LogicalAndReverse | 逻辑运算:反转与 (s & !d) 仅限 DX11.1。 |
LogicalAndInverted | 逻辑运算:逆与 (s & d) 仅限 DX11.1。 |
LogicalOrReverse | Logical operation: Reverse Or (s | !d) DX11.1 only. |
LogicalOrInverted | Logical operation: Inverted Or (!s | d) DX11.1 only. |
混合系数
以下所有属性对 Blend 命令中的 SrcFactor 和 DstFactor 都有效。源是指计算所得颜色,目标是指屏幕上已有的颜色。如果 BlendOp 在使用逻辑运算,则将忽略混合系数。
One | 值为 1 - 让源或目标颜色通过。 |
Zero | 值为 0 - 删除源或目标值。 |
SrcColor | 此阶段的值乘以源颜色值。 |
SrcAlpha | 此阶段的值乘以源 Alpha 值。 |
DstColor | 此阶段的值乘以帧缓冲区源颜色值。 |
DstAlpha | 此阶段的值乘以帧缓冲区源 Alpha 值。 |
OneMinusSrcColor | 此阶段的值乘以(1 - 源颜色)。 |
OneMinusSrcAlpha | 此阶段的值乘以(1 - 源 Alpha)。 |
OneMinusDstColor | 此阶段的值乘以(1 - 目标颜色)。 |
OneMinusDstAlpha | 此阶段的值乘以(1 - 目标 Alpha)。 |
ColorMask
ColorMask RGB | A | 0 | R、G、B、A 的任意组合
设置颜色通道写入遮罩。写入 ColorMask 0 可关闭对所有颜色通道的渲染。默认模式是 写入所有通道 (RGBA),但是对于某些特殊效果,您可能希望不修改某些通道,或完全禁用颜色 写入。
使用多渲染目标 (MRT) 渲染时,可通过在末尾添加索引(0 到 7)来为每个渲染目标设置不同的颜色遮罩。例如,ColorMask RGB 3 将使渲染目标 #3 仅写入到 RGB 通道。
固定函数 Lighting 和 Material
Lighting On | Off
Material { Material Block }
SeparateSpecular On | Off
Color Color-value
ColorMaterial AmbientAndDiffuse | Emission
所有这些均控制固定函数每顶点光照:它们将其开启,设置材质颜色,开启镜面高光,提供默认颜色(如果顶点光照关闭),并控制网格顶点颜色如何影响光照。请参阅有关材质的文档以了解更多详细信息。
固定函数 Fog
Fog { Fog Block }
设置固定函数 Fog 的参数。请参阅有关雾化的文档以了解更多详细信息。
固定函数 AlphaTest
AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue
开启固定函数 Alpha 测试。请参阅有关 Alpha 测试的文档以了解更多详细信息。
固定函数纹理组合器
设置渲染状态后,可使用 SetTexture 命令指定多个纹理及其组合模式:
SetTexture textureProperty { combine options }
Pass Tags
LightMode
光照模式,内建值包括:
- Always:总是渲染,不使用光照
- ForwardBase:用于前向渲染,使用环境光、主平行光、顶点/SH(球谐函数)光照以及光照贴图
- ForwardAdd:用于前向渲染,额外使用每像素光,每个光照一个通道
- Deferred:用于延迟着色,渲染G-Buffer
- ShadowCaster:渲染对象的深度到阴影贴图或者深度纹理
- PrepassBase:用于(旧版)延迟光照,渲染法线和高光指数
- PrepassFinal:用于(旧版)延迟光照,合并贴图、光照和自发光来渲染最终色彩
- Vertex:当对象不受光照贴图影响的时候,用来渲染(旧版)顶点发光。适用所有的顶点光照
- VertexLMRGBM:当对象接受光照贴图影响的时候,用来渲染(旧版)顶点发光。适用于使用RGBM编码光照贴图的平台(PC&主机)
- VertexLM:当对象接受光照贴图影响的时候,用来渲染(旧版)顶点发光。适用于使用double-LDR编码光照贴图的平台(移动平台)
PassFlags
标志渲染管线如何传递数据给通道 OnlyDirectional:只有主平行光、环境光和光照探测器的数据会传递给通道,适用于LightMode为ForwardBase
RequireOptions
标志通道至于在某些外部条件满足时才会被渲染 SoftVegetation:当Quality Setting中的Soft Vegetation选项被开启时,才会渲染通道
GrabPass
GrabPass { "_RefractionTex" }
GrabPass 该Pass负责抓取屏幕并将结果存储到一张纹理中,以用于后续的Pass处理。 通常用来实现玻璃等透明材质的模拟,与使用简单的透明混合不同,使用 GrabPass 可以让我们对该物体后面的图像进行更复杂的处理。
- 直接使用 GrabPass { },然后再后续的Pass中直接使用GrabTexture来访问屏幕图像。但是,当场景中有多个物体都使用了这样的形式来抓取屏幕时,这种方法的性能消耗比较大,因为对于每一个使用它的物体,Unity都会为它单独进行一次昂贵的屏幕抓取操作。但这种方法可以让每个物体得到不同的屏幕图像,这取决于它们的渲染队列及渲染它们时当前的屏幕缓冲中的颜色。
- 使用 GrabPass { “TextureName” },我们可以在后续的Pass中使用TextureName来访问屏幕图像。使用这种方法同样可以抓取屏幕,但Unity只会在每一帧时为第一个使用名为TextureName的纹理的物体执行一次抓取屏幕的操作,而这个纹理同样可以在其它Pass中被访问。这种方法更高效,因为不管场景中有多少物体使用了该命令,每一帧中Unity都只会执行一次抓取工作,但这也意味着所有物体都会使用同一张屏幕图像。不过,在大多数情况下这已经足够了。
Usepass
该命令用来复制其他UnityShader的Pass
补充
属性
Properties { Property [Property ...]}
定义属性代码块。在大括号内,多个属性定义如下。
数字和滑动条
name ("display name", Range (min, max)) = number
name ("display name", Float) = number
name ("display name", Int) = number
这些全都定义一个具有默认值的数字(标量)属性。Range
格式使该属性显示为一个滑动条,范围在 min 到 max 之间。
颜色和矢量
name ("display name", Color) = (number,number,number,number)
name ("display name", Vector) = (number,number,number,number)
使用给定 RGBA 分量的默认值定义颜色属性,或使用默认值定义 4D 矢量属性。颜色属性会显示拾色器,并根据颜色空间按需进行调整。矢量属性显示为四个数字字段。
纹理
name ("display name", 2D) = "defaulttexture" {}
name ("display name", Cube) = "defaulttexture" {}
name ("display name", 3D) = "defaulttexture" {}
顶点数据语意
POSITION
是顶点位置,通常为float3
或float4
。NORMAL
是顶点法线,通常为float3
。TEXCOORD0
是第一个 UV 坐标,通常为float2
、float3
或float4
。TEXCOORD1
、TEXCOORD2
和TEXCOORD3
分别是第 2、第 3 和第 4 个 UV 坐标。TANGENT
是切线矢量(用于法线贴图),通常为float4
。COLOR
是每顶点颜色,通常为float4
。
编译指令
- #pragma vertex name - 作为顶点着色器来编译函数 name。
- #pragma fragment name - 作为片元着色器来编译函数 name。
- #pragma geometry name - 作为 DX10 几何着色器来编译函数 name。如下所述,设置此选项会自动开启 #pragma target 4.0。
- #pragma hull name - 作为 DX11 外壳着色器来编译函数 name。如下所述,设置此选项会自动开启 #pragma target 5.0。
- #pragma domain name - 作为 DX11 域着色器来编译函数 name。如下所述,设置此选项会自动开启 #pragma target 5.0。
其他编译指令
- #pragma target name - 要编译到的着色器目标。有关详细信息,请参阅着色器编译目标页面。
- #pragma require feature …- 对着色器需要的 GPU 功能进行精细控制,请参阅着色器编译目标页面以了解详细信息。
- #pragma only_renderers 空格分隔的名称 - 仅为给定的渲染器编译着色器。默认情况下,将为所有渲染器编译着色器。
- #pragma exclude_renderers 空格分隔的名称 - 不为给定渲染器编译着色器。默认情况下,将为所有渲染器编译着色器。
- #pragma multi_compile … - 用于处理多个着色器变体。
- #pragma enable_d3d11_debug_symbols - 为针对 DirectX 11 编译的着色器生成调试信息,这将允许您通过 Visual Studio 2012(或更高版本)图形调试器来调试着色器。
- #pragma hardware_tier_variants 渲染器名称 - 为每个可以运行所选渲染器的硬件层生成每个编译着色器的多个着色器硬件变体。
- #pragma hlslcc_bytecode_disassembly - embed disassembled HLSLcc bytecode into translated shader.
- #pragma disable_fastmath - enables precise IEEE 754 rules, mostly involving NaN handling (currently only affects Metal platform).
- #pragma glsl_es2 - When set in a GLSL shader, generate a GLSL ES 1.0(OpenGL ES 2.0), even when the shader target is OpenGL ES 3.
每个代码片段必须至少包含一个顶点程序和一个片元程序。因此,#pragma vertex 和 #pragma fragment 指令是必需的。