ShaderLab Syntax
unity中所有的shader文件都是用“ShaderLab”语言编写的在该文件中,嵌套大括号语法声明了描述着色器的各种内容– for 例如哪些材质属性应该显示在材质inspector中,要做什么样的硬件备份,需要什么样的混合模式,真正的 “shader code” 是写在CGPROGRAM
片段里面
Shader 是着色器文件的根命令。每个文件必须定义一个(且只有一个)着色器。它指定使用这个着色器的对象如何被渲染。
Syntax
Shader "name" { [Properties] __Subshaders__ [Fallback] [CustomEditor] }
定义一个 shader. 它会在材质的属性面板下显示shader的 name.
Details
Properties
属性在材质的属性面板上显示出来,典型的属性是被着色器使用的对象颜色、纹理或任意值。
SubShaders & Fallback
每个着色器由 sub-shaders的一个列表组成,你必须至少有一个 .当加载shader时,unity会找到subshader列表中的第一个能被终端设备支持的subshader,如果没有就是用 fallback shader.
不同的显卡加载能力不一样,你想把一个完美的效果呈现在最高端的机器上,但是并不是所有人的设备都是最高端的,所以这就是subshader的作用,创建一个subshader拥有完美的效果,然后为旧显卡添加更多的subshader,这些子着色器可能以一种较慢的方式实现您想要的效果,或者它们可能选择不实现某些细节。
Shader “level of detail” (LOD) and “shader replacement” 是两种基于subshaders的技术, see Shader LOD and Shader Replacemement for details.
Examples
Here is one of the simplest shaders possible:
// colored vertex lighting
Shader "Simple colored lighting"//声明shader的名字
{// a single color propertyProperties {_Color ("Main Color", Color) = (1,.5,.5,1)}// define one subshaderSubShader{// a single pass in our subshaderPass{// use fixed function per-vertex lightingMaterial{Diffuse [_Color]}Lighting On}}
}
定义了一个 color 属性变量_Color (在material inspector 显示为 Main Color) 默认值为 (1,0.5,0.5,1). subshader由一个Pass ,它的功能是打开顶点光照,设置基本材质
See more complex examples at Surface Shader Examples or Vertex and Fragment Shader Examples.
ShaderLab: Properties
着色器可以定义一个参数列表,由开发者在Unity的材质属性面板中设置。
Syntax
Properties
Properties { Property [Property ...] }
定义属性块。在大括号内定义了多个属性,如下所示。
数字和滑块(Number and Slider)
name ("display name", Range (min, max)) = number
name ("display name", Float) = number
name ("display name", Int) = number
这些都定义了一个带有默认值的number (scalar)属性. Range
会定义一个滑动块,在最大值和最小值之间
颜色和向量(Colors and Vectors)
name ("display name", Color) = (number,number,number,number)
name ("display name", Vector) = (number,number,number,number)
默认颜色是RGBA四个值, or或者一个四维向量 . Color 属性有一个颜色面板的选择器,你可以自己选择颜色,Vector属性被展示成四个数字区域
材质(Textures)
name ("display name", 2D) = "defaulttexture" {}
name ("display name", Cube) = "defaulttexture" {}
name ("display name", 3D) = "defaulttexture" {}
Defines a 2D texture, cubemap or 3D (volume) property respectively.
Details
每一个属性值在 shader 是通过 name 引用的(在unity里面,一般使用下划线来命名属性).属性名会显示在属性面板上
对于每个属性,等于号后面都有一个默认值:
- Range和Float类型,就是一个数字,比如 “13.37”.
- Color 和 Vector 它是括号里的四个数字, 比如“(1,0.5,0.2,1)”.
- 2D Textures, 默认值是一个空字符串,或者是一个内置的默认纹理,比如: “white” (RGBA: 1,1,1,1), “black” (RGBA: 0,0,0,0), “gray” (RGBA: 0.5,0.5,0.5,0.5), “bump” (RGBA: 0.5,0.5,1,0.5) or “red” (RGBA: 1,0,0,0).
- (Cube, 3D, 2DArray)默认值是一个空字符串.当材质没有分配Cubemap/3D/数组纹理时,使用灰色纹理(RGBA: 0.5,0.5,0.5,0.5)。
稍后在着色器的固定功能部分, 可以使用方括号中的属性名访问属性值: [name].例如,您可以通过material属性声明两个整数来驱动混合模式(比如 “SrcBlend“ and ”DstBlend”), 然后使用 Blend Command 来调用他们: Blend [_SrcBlend] [_DstBlend]
.
在 Properties
块中的参数 作为 Material的序列化数据,. Shader 可以由很多参数,比如(like matrices, vectors and floats) 这些参数可以在脚本运行时使用, 但是如果它们不是 Properties 块中的变量,它们的值是不会被保存的.这对于完全由脚本代码驱动的值非常有用 (using Material.SetFloat and similar functions).
Property attributes and drawers
在任何属性前面,都可以指定方括号中的可选属性,这些属性可以被Unity识别,或者它们可以通过MaterialPropertyDrawer类,以控制它们在material inspector中应该如何呈现. Unity中的Attributes :
[HideInInspector]
- 在材质inspector中不显示属性值[NoScaleOffset]
- material inspector不会显示 texture tiling/offset (平铺/偏移)区域[Normal]
-显示 texture property 需要一个法线贴图 normal-map.[HDR]
- 显示texture property 需要一个高动态范围贴图 high-dynamic range (HDR) texture.[Gamma]
- 显示 float/vector被声明为 sRGB的值,并可根据所使用的色彩空间进行转换. See Properties in Shader Programs.[PerRendererData]
-指示纹理属性将以MaterialPropertyBlock的组成形式来呈现. Material改变这些texture用户界面。
Example
// properties for a water shader
Properties
{_WaveScale ("Wave scale", Range (0.02,0.15)) = 0.07 // sliders_ReflDistort ("Reflection distort", Range (0,1.5)) = 0.5_RefrDistort ("Refraction distort", Range (0,1.5)) = 0.4_RefrColor ("Refraction color", Color) = (.34, .85, .92, 1) // color_ReflectionTex ("Environment Reflection", 2D) = "" {} // textures_RefractionTex ("Environment Refraction", 2D) = "" {}_Fresnel ("Fresnel (A) ", 2D) = "" {}_BumpMap ("Bumpmap (RGB) ", 2D) = "" {}
}
ShaderLab: SubShader
每一个shader都有多个subshader组成,当unity要显示一个网格,它会找到要使用的着色器,并选择在用户的显卡上运行的第一个subshader
Syntax
Subshader { [Tags] [CommonState] Passdef [Passdef ...] }
subshader包括 optional tags, common state 和多个pass定义.
Details
一个 subshader有用多个渲染通道 rendering passes and optionally 设置,任何state 对所有的 passes都是通用的. 除此之外, subshader 可以设置特定的标记Tag
当Unity选择一个subshader渲染, 它会为每一个渲染通道都传递该物体去渲染(可能更多的是由于光的相互作用. 每一个pass耗性能,所以尽可能地少. 当然有时候显卡要显示一个效果,一个pass完成不了,这时候就需要多个pass
pass分为 regular Pass, a Use Pass or a Grab Pass.
Pass定义的任何语句也出现在Subshade块中。所有的Pass使用这个“共享”state。
Example
// ...
SubShader {Pass {Lighting OffSetTexture [_MainTex] {}}
}
// ...
这个subshader 定义了一个 Pass,关闭所有的灯光,显示一个带有 _MainTex.的网格
ShaderLab: Pass
Pass 块让游戏物体被渲染一次
Syntax
Pass { [Name and Tags] [RenderSetup] }
一个 Pass 命令包含多个 渲染状态设置命令.
Name and tags
一个 Pass可以定义其 Nam名称和任意数量的Tags标签,这些 name/value 字符串将传递给渲染引擎
Render state set-up
Pass设置图形硬件的各种状态,比如是否打开alpha混合或者是否使用depth testing深度测试。
比如:
Cull
设置多边形裁剪模式。
Cull Back | Front | Off
设置depth buffer深度缓冲测试模式
ZTest
ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)
设置depth buffer写入模式 writing mode.
ZWrite
ZWrite On | Off
设置Z buffer depthZ缓冲深度偏移
Offset
Offset OffsetFactor, OffsetUnits
Blend
Blend sourceBlendMode destBlendMode
Blend sourceBlendMode destBlendMode, alphaSourceBlendMode alphaDestBlendMode
BlendOp colorOp
BlendOp colorOp, alphaOp
AlphaToMask On | Off
Sets alpha blending, alpha operation, and alpha-to-coverage modes. See documentation on Blending for more details.
ColorMask
ColorMask RGB | A | 0 | any combination of R, G, B, A
设置彩色通道写入蒙版. ColorMask 0 关闭所有的颜色渲染通道. 默认是 (RGBA),显示所有的的渲染通道, 但是对于某些特殊效果,您可能希望保留某些通道不进行修改,或者完全禁用颜色写入
当使用多个渲染目标(MRT)渲染时,可以为每个渲染目标设置不同的颜色遮罩,通过在末尾添加索引(0-7)。例如,ColorMask RGB 3将使呈现目标#3只写入RGB通道。
Legacy fixed-function Shader commands:命令行
命令行编写shader的功能 “fixed-function style” Shaders. 这被认为是不受欢迎的功能,但是对于非常简单的着色器,以固定函数的形式编写它们有时会更容易,注意,如果不使用固定函数着色器,下面的所有命令都将被忽略。
Fixed-function Lighting and Material
Lighting On | Off
Material { Material Block }
SeparateSpecular On | Off
Color Color-value
ColorMaterial AmbientAndDiffuse | Emission
这些控制命令控制每个顶点的光照情况: 打开光照, 设置Material 颜色, 打开高光 specular highlights, 提供默认颜色 default color (如果顶点光照关闭的话), and 控制 mesh顶点如何影响光照
Fixed-function Fog:打开雾状效果
Fog { Fog Block }
Fixed-function AlphaTest:打开alpha测试
AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue
Fixed-function Texture combiners:打开材质合并
在设置 render state 之后,使用 SetTexture 命令指定一些纹理和他们的组合模式:
SetTexture textureProperty { combine options }
Details
着色通道与Unity的渲染管道以多种方式交互; 比如:一个Pass可以使用Tags命令指示它只能用于deferred shading延迟着色某些passes也可以在同一个GameObject上执行多次; 例如,在前向渲染forward rendering中,“前向添加”“ForwardAdd”的pass类型会根据影响游戏对象的灯光数量被执行多次
ShaderLab culling and depth testing:裁剪和深度测试
剔除是一种优化,它不渲染那些离视角远的面,或者是背面,所有的多边形都有正面和背面; 如果你有一个立方体,你将永远不会看到面朝你以外的边(总是有一面朝你在它的前面),所以Unity不需要画面朝外的边。因此有了Backface culling”这个术语
另一个使渲染看起来正确的特性是Depth testing。Depth testing确保在一个场景中只绘制最近的表面对象
.
Syntax
Cull
Cull Back | Front | Off
控制应该裁剪多边形的哪些边(而不是绘制)
- Back 背面裁剪,默认设置
- Front 不要渲染面向观察者的多边形。用于将物体由内向外翻转。
- Off 禁用剔除-所有面都被绘制。用于特殊效果。
ZWrite
ZWrite On | Off
控制是否将来自此对象的像素写入深度缓冲区(默认是 On). 如果你画的是实心物体,把这个开着。如果你正在绘制半透明效果,把这个关闭
ZTest
ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always
应如何进行深度测试.默认是 LEqual (绘制现有对象或在现有对象的距离内绘制对象,隐藏它们后面的对象)
Offset
Offset Factor, Units
允许你用两个参数进行深度偏移. factor and units. Factor 缩放z最大斜率,对于多边形的X或Y, and units为最小可分解深度缓冲值. 这允许你强迫一个多边形画在另一个上面,尽管它们实际上是在相同的位置. 比如:Offset 0, -1
将多边形拉近摄像机,忽略多边形的斜率,Offset -1, -1
将拉多边形更接近时,看一个擦角
Examples
:这个对象将只渲染一个对象的背面:
Shader "Show Insides" {__SubShader__ {Pass {Material {Diffuse (1,1,1,1)}Lighting OnCull Front}}
}
Transparent shader with depth writes
通常 semitransparent shaders 不写入深度缓存.,但是这可能会产生绘制顺序问题,特别是对于复杂的非凸网格.如果你想要像淡入淡出的(半透明)网格,那么在渲染透明度之前使用填充深度缓存的着色器可能会有用。
Semitransparent object; left: standard Transparent/Diffuse shader; right: shader that writes to depth buffer.
Shader "Transparent/Diffuse ZWrite" {
Properties {_Color ("Main Color", Color) = (1,1,1,1)_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
}
SubShader {Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}__LOD__ 200// extra pass that renders to depth buffer onlyPass {ZWrite OnColorMask 0}// paste in __forward rendering__ passes from Transparent/DiffuseUsePass "Transparent/Diffuse/FORWARD"
}
Fallback "Transparent/VertexLit"
}
Debugging Normals:调式法线
首先,我们使用普通的顶点光照渲染对象, 然后我们把背面成亮粉色. 它的效果是在任何需要法线翻转的地方高亮显示.如果粉色部分是可见的,那么会吸收那些靠近它的物体
Here we go:
Shader "Reveal Backfaces" {Properties {_MainTex ("Base (RGB)", 2D) = "white" { }}SubShader {// Render the front-facing parts of the object.// We use a simple white material, and apply the main texture.Pass {Material {Diffuse (1,1,1,1)}Lighting OnSetTexture [_MainTex] {Combine Primary * Texture}}// Now we render the back-facing triangles in the most// irritating color in the world: BRIGHT PINK!Pass {Color (1,0,1,1)Cull Front}}
}
Glass Culling:玻璃剔除
如果你有个半透明物体,你能看到它的背面. 你如你什么都不剔除(Cull Off), 可能会有一些背面和正面重叠
这个shader用于(spheres, cubes, car windscreens).
Shader "Simple Glass" {Properties {_Color ("Main Color", Color) = (1,1,1,0)_SpecColor ("Spec Color", Color) = (1,1,1,1)_Emission ("Emmisive Color", Color) = (0,0,0,0)_Shininess ("Shininess", Range (0.01, 1)) = 0.7_MainTex ("Base (RGB)", 2D) = "white" { }}SubShader {// We use the material in many passes by defining them in the subshader.// Anything defined here becomes default values for all contained passes.Material {Diffuse [_Color]Ambient [_Color]Shininess [_Shininess]Specular [_SpecColor]Emission [_Emission]}Lighting OnSeparateSpecular On// Set up alpha blendingBlend SrcAlpha OneMinusSrcAlpha// Render the back facing parts of the object.// If the object is convex, these will always be further away// than the front-faces.Pass {Cull FrontSetTexture [_MainTex] {Combine Primary * Texture}}// Render the parts of the object facing us.// If the object is convex, these will be closer than the// back-faces.Pass {Cull BackSetTexture [_MainTex] {Combine Primary * Texture}}}
}
ShaderLab: Blending
Blending 混合模式用来制作半透明物体
当显卡渲染物体时, 在所有的texture和shader执行完毕后, 像素才会渲染到屏幕上.怎样将像素和已有的内存组合到一起,是由Blend命令控制的
Syntax
Blend Off
: 关闭混合模式,这是默认的
Blend SrcFactor DstFactor
:生成的颜色乘以 SrcFactor. 已经存在的颜色乘以DstFactor ,然后这两个混合
Blend SrcFactor DstFactor, SrcFactorA DstFactorA
: 和上面一样,但是使用两个不同的 factors 混合alpha通道
BlendOp Op
:与其添加混合色,不如对它们进行不同的操作。
BlendOp OpColor, OpAlpha
: 和上面一样,但是对颜色(RGB)和alpha (A)通道使用不同的混合操作。
此外,您可以设置upper-rendertarget混合模式.当使用多重渲染目标(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对pixel shader导致的alpha值修改多重采样覆盖的比例,对植被和其它透明通道的物体非常有用
Blend operations
可以使用一下混合操作:
Add | Add source and destination together.将源和目标添加在一起 |
Sub | Subtract destination from source.将目标从源里减去 |
RevSub | Subtract source from destination. |
Min | Use the smaller of source and destination. |
Max | Use the larger of source and destination. |
LogicalClear | Logical operation: Clear (0) DX11.1 only. |
LogicalSet | Logical operation: Set (1) DX11.1 only. |
LogicalCopy | Logical operation: Copy (s) DX11.1 only. |
LogicalCopyInverted | Logical operation: Copy inverted (!s) DX11.1 only. |
LogicalNoop | Logical operation: Noop (d) DX11.1 only. |
LogicalInvert | Logical operation: Invert (!d) DX11.1 only. |
LogicalAnd | Logical operation: And (s & d) DX11.1 only. |
LogicalNand | Logical operation: Nand !(s & d) DX11.1 only. |
LogicalOr | Logical operation: Or (s | d) DX11.1 only. |
LogicalNor | Logical operation: Nor !(s | d) DX11.1 only. |
LogicalXor | Logical operation: Xor (s ^ d) DX11.1 only. |
LogicalEquiv | Logical operation: Equivalence !(s ^ d) DX11.1 only. |
LogicalAndReverse | Logical operation: Reverse And (s & !d) DX11.1 only. |
LogicalAndInverted | Logical operation: Inverted And (!s & d) DX11.1 only. |
LogicalOrReverse | Logical operation: Reverse Or (s | !d) DX11.1 only. |
LogicalOrInverted | Logical operation: Inverted Or (!s | d) DX11.1 only. |
Blend factors
下面的属性对SrcFactor & DstFactor都有用. Source 是计算的出来的颜色, Destination 是屏幕上已经存在的颜色.如果BlendOp使用logical operations,则忽略blend factors。
One | 使用它来让源颜色或目标颜色完全通过。 |
Zero | 使用它来删除源值或目标值 |
SrcColor | 此阶段的值乘以源颜色值。 |
SrcAlpha | 此阶段的值乘以源颜色的alpha值 |
DstColor | 此阶段的值乘以帧缓冲源颜色值The value of this stage is multiplied by frame buffer source color value. |
DstAlpha | The value of this stage is multiplied by frame buffer source alpha value. |
OneMinusSrcColor | The value of this stage is multiplied by (1 - source color). |
OneMinusSrcAlpha | The value of this stage is multiplied by (1 - source alpha). |
OneMinusDstColor | The value of this stage is multiplied by (1 - destination color). |
OneMinusDstAlpha | The value of this stage is multiplied by (1 - destination alpha). |
Details
下面是常用的 blend types
:
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
Alpha blending, alpha testing, alpha-to-coverage
For drawing mostly fully opaque or fully transparent objects, where transparency is defined by the Texture’s alpha channel (e.g. leaves, grass, chain fences etc.), several approaches are commonly used:
Alpha blending
Regular alpha blending
This often means that objects have to be considered as “semitransparent”, and thus can’t use some of the rendering features (for example: deferred shading, can’t receive shadows). Concave or overlapping alpha-blended objects often also have draw ordering issues.
Often, alpha-blended Shaders also set transparent render queue, and turn off depth writes. So the Shader code looks like:
// inside SubShader
Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }// inside Pass
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Alpha testing/cutout
clip() in pixel Shader
By using clip()
HLSL instruction in the pixel Shader, a pixel can be “discarded” or not based on some criteria. This means that object can still be considered as fully opaque, and has no draw ordering issues. However, this means that all pixels are fully opaque or transparent, leading to aliasing (“jaggies”).
Often, alpha-tested Shaders also set cutout render queue, so the Shader code looks like this:
// inside SubShader
Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }// inside __CGPROGRAM__ in the __fragment Shader__:
clip(textureColor.a - alphaCutoffValue);
Alpha-to-coverage
AlphaToMask On, at 4xMSAA
当使用多重采样反锯齿(MSAA,参见QualitySettings)时,可以通过使用alpha-to-coverage GPU功能来改进alpha测试方法。根据使用的MSAA级别,这可以改进边缘外观。
这种功能最适用于大部分不透明或透明的纹理,并且具有非常薄的“部分透明”区域(草地、树叶等)。
通常,alpha-to-coverage着色器也会设置cutout渲染队列.
// inside SubShader
Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }// inside Pass
AlphaToMask On
Example
添加一个贴图到屏幕上
Shader "Simple Additive" {Properties {_MainTex ("Texture to blend", 2D) = "black" {}}__SubShader__ {Tags { "Queue" = "Transparent" }Pass {Blend One OneSetTexture [_MainTex] { combine texture }}}
}
ShaderLab: Pass Tags
Passes 使用tags告诉如何以及何时将它们呈现到 rendering engine中
Syntax
Tags { "TagName1" = "Value1" "TagName2" = "Value2" }
Details
Tags 是一些键值对,用于控制此pass通道在照明管道lighting pipline中的角色 (ambient, vertex lit, pixel lit etc.)
注意:下面的tags只能放在pass当中,不能放在subshader中
LightMode tag
LightMode tag 定义了照明管道中的Pass 角色.See render pipeline for details. 这些tags很少手动使用,大多数是在shader和灯光有交互的时候才使用,大多数情况下,需要与光照交互的着色器被写为表面着色器,然后处理所有这些细节。
下面是LightMode 标签的值:
- Always: 总是呈现;在没有灯光的情况下也渲染。.
- ForwardBase:用于 Forward rendering, ambient, main directional light, vertex/SH lights and lightmaps are applied.
- ForwardAdd: 用于 Forward rendering; 应用每个像素的附加光,每个光通过一次。
- Deferred: 用于Deferred Shading;
- ShadowCaster: 渲染物体深度到shadowmap阴影贴图或 depth texture.深度纹理
- MotionVectors:用于计算每个物体的运动矢量。
- PrepassBase: 用于 legacy Deferred Lighting, 渲染法线和高光指数。.
- PrepassFinal: 用于 legacy Deferred Lighting, 渲染最后的颜色,组合纹理,照明和自发光。.
- Vertex: 用于 legacy Vertex Lit rendering 当物体没有光照映射时候使用顶点光照渲染,所有的顶点灯都被应用
- VertexLMRGBM: Used in legacy Vertex Lit rendering when object is lightmapped; on platforms where lightmap is RGBM encoded (PC & console).
- VertexLM: Used in legacy Vertex Lit rendering when object is lightmapped; on platforms where lightmap is double-LDR encoded (mobile platforms).
PassFlags tag
pass可以声明一个改变rendering pipeline向其传递数据方式的tag. 使用 PassFlags 标签, 目前支持的值有:
- OnlyDirectional:当使用 ForwardBase pass 类型时, 这个标志使得只有 main directional light主方向光和ambient/lightprobe环境光/光照探头数据被传递到着色器中。 makes it so that only the main directional light and ambient/lightprobe data is passed into the shader. 这意味着不重要的光的数据不会传递到顶点光或球面谐波着色器变量当中. See Forward rendering for details.
RequireOptions tag
一个pass可以表明它只应该在满足某些外部条件时才被呈现.使用 RequireOptions tag, 目前
支持
- SoftVegetation: 只有Quality window.窗口下的Soft VegetationRender打开,这个通道才能被渲染
ShaderLab: SubShader Tags
Syntax
Tags { "TagName1" = "Value1" "TagName2" = "Value2" }
Details
Tags标签基本上是键值对。子着色器内部的tag用来决定子着色器的渲染顺序和其他参数 .
除了, unity内置的标签,你也可以使用你自己的标签,并且可以用Material.GetTag来获得它们
Rendering Order - Queue tag:渲染顺序标签
使用Queue tag确定对象的渲染顺序, Shader决定了它的对象属于哪个渲染队列, 这样:任何透明着色器都可以确保它们是在所有不透明对象之后绘制的
下面是四个预定义的呈现队列,:但是在预定义的队列之间可以有更多的队列. 预定义的队列是:
Background
- 此呈现队列先于任何其他队列呈现. 你通常会把它用在需要在后台的东西上,先渲染的肯定最后面,所以可以当背景.Geometry
(default) - 这用于大多数对象。不透明几何使用这个队列。AlphaTest
- alpha tested 的几何体使用这个队列. 它是一个独立于Geometry的队列,因为在绘制完所有实体对象之后,渲染经过alpha测试的对象更有效。Transparent
-这个在 Geometry andAlphaTest之后渲染
,从前往后的顺序。任何alpha混合(即着色器不写入深度缓冲)应该到这里(玻璃,粒子效果)。Overlay
-这个渲染队列用于叠加效果.最后渲染的东西都应该放到这里(比如镜头光斑)
Shader "Transparent Queue Example"
{SubShader{Tags { "Queue" = "Transparent" }Pass{// rest of the shader body...}}
}
在内部,每个队列由整数索引表示; Background
is 1000, Geometry
is 2000, AlphaTest
is 2450, Transparent
is 3000 and Overlay
is 4000. If a shader uses a queue like this:
Tags { "Queue" = "Geometry+1" }
渲染的顺序是从小往大,越小的值越先被渲染,和摄像机的depth一样, 这让你可以自己定义对象渲染的顺序. 例如,在大多数情况下,透明的水应该画在不透明的物体之后,但在透明物体之前
队列在2500以上,被认为是 “opaque”物体,并能达到最好的性能效果,较高的渲染队列,被认为是透明物体,它会按照游戏物体的距离分类,从最远的开始渲染,到最近的结束,天空盒会在“opaque”和“transparent”之间
RenderType tag
RenderType
tag 将着色器分成几个预定义的组,一个opaque shader, 或者一个 alpha-tested shader etc. 这是用着色器替代和在某些情况下用来产生相机的深度纹理。This is used by Shader Replacement and in some cases used to produce camera’s depth texture.
Rendering with Replaced Shaders--->shader replacement
有些渲染效果需要使用不同的着色器来渲染场景。例如,好的边缘检测需要一个具有scene normals场景法线的纹理,这样它就可以检测出表面方向不同的边缘。其他效果可能需要一个具有场景深度的texture,为了实现这一点,可以使用替换所有对象的着色器来渲染场景
Shader replacement 可以通过脚本代码 Camera.RenderWithShader or Camera.SetReplacementShader 实现.这两个函数都接收一个shader参数,和一个replacement tag ,游戏物体仍然使用它们的材质球,但是实际的shader 改变了
- If replacementTag为空,使用给定的替换着色器渲染场景中的所有对象.
- If replacementTag 不为空,为以如下方式渲染物体:
- 真实物体的shader会查询 tag value的值.
- 如果没有tag,物体不渲染.
- 在替换着色器中找到一个subshader,并且有tag,如果没有subshader,则不被渲染
- 现在subshader被用来渲染对象
如果所有的shader都有一个“RenderType” tag ,值像 “Opaque”, “Transparent”, “Background”, “Overlay”一样,你可以写一个替换shader,它只有一个subshader,使用RenderType=Solid tag,只渲染固态物体,或者你可以为不同的“RenderType”标签值写几个子着色器。顺便说一句,所有内置的Unity着色器都有一个“RenderType”标签集
Lit shader replacement
当使用着色器替换时,场景是使用相机上配置的渲染路径来渲染的.这意味着用于替换的着色器可以包含阴影和照明通道 (你可以使用表面着色器来表示替换着色器)。这对于渲染特殊效果和场景调试非常有用.
Shader replacement tags in built-in Unity shaders:内置的tag
- Opaque: 大多数 shaders (Normal, Self Illuminated, Reflective, terrain shaders).
- Transparent: 大多数半透明物体 (Transparent, Particle, Font, terrain additive pass shaders).
- TransparentCutout: 带有透明剔除的物体(Transparent Cutout, two pass vegetation shaders).
- Background:天空盒 Skybox shaders.
- Overlay: GUITexture, Halo, Flare shaders.
- TreeOpaque: terrain engine 树皮.
- TreeTransparentCutout: terrain engine 树叶
- TreeBillboard: terrain engine 始终正面朝向摄像机的树.
- Grass: terrain engine 草
- GrassBillboard: terrain engine billboarded grass始终正面朝向摄像机的草.
Built-in scene depth/normals texture
摄像机有内置的非常复杂的 render depth 或者depth+normals texture,如果你想使用看 Camera Depth Texture 这一页. 注意,在某些情况下(取决于硬件),深度和深度+法线纹理可以在内部使用着色器替代渲染。所以在着色器中使用正确的“RenderType”标签是很重要的。
Code Example
在start函数里面声明要替换的shader
void Start() {camera.SetReplacementShader (EffectShader, "RenderType");
}
这要求EffectShader 使用 RenderType 的键. EffectShader 会有你想要的 RenderType 的键值对
Shader "EffectShader" {SubShader {Tags { "RenderType"="Opaque" }Pass {...}}SubShader {Tags { "RenderType"="SomethingElse" }Pass {...}}...}
SetReplacementShader会浏览场景中所有的对象,不是使用它们本来的shader,而是使用sub键值对相匹配的subshader,比如:Rendertype=“Opaque” tag 的shader 将会被EffectShader的第一个subshader代替, 所有RenderType=“SomethingElse”的 shader会使用第二个subshader替代. 没有和EffectShader相匹配的键值对的物体,不被渲染
DisableBatching tag
一些着色器(主要是对象空间顶点变形的着色器)在绘制调用批处理时不起作用 – 这是因为批处理将所有几何图形转换为世界空间,因此“对象空间”丢失了。
DisableBatching
.由三个值: “True” (总是禁用此着色器的批处理), “False” (不禁用批处理;这是默认的) and “LODFading” (当LOD fading 打开时禁用,大多数情况用在树上).
ForceNoShadowCasting tag
If ForceNoShadowCasting
如果为 “True”, 游戏物体将不会有阴影. 这对使用这个shader替代那些你不想有阴影的透明物体的shader非常有用
IgnoreProjector tag
If IgnoreProjector
如果为“True”, 它们不会被 Projectors 影响,这对半透明物体很有用
CanUseSpriteAtlas tag
Set CanUseSpriteAtlas
tag 为 “False”如果shader是用来 sprites的,当sprite ans被打包近图集时候,他将不会工作
PreviewType tag
PreviewType
表示在材质面板上如何显示preview视图 ,默认是一个球, PreviewType 可以被设置为 “Plane” (will display as 2D) or “Skybox” (will display as skybox).