在我们写unity shader的时候经常会遇到要定义一些shader tags的时候,但是又不能知道到底要设置哪些状态,有哪些状态可以设置,每次都要去网上搜索,感觉很麻烦,因此特地整理了一下,以便以后需要用的时候查阅。

Unity shaderLab 中的Tags一起包括2类:

  • ShaderLab: SubShader Tags
  • ShaderLab: Pass Tags
  • Own tags

    一个是定义在subshade中的Tags 一个是定义在Pass中的Tags,以及可以使用自定义的Tags, 下面分别对这几种Tags进行说明。

Tags的定义形式:

   

Tags { "TagName1" = "Value1" "TagName2" = "Value2" }

ShaderLab: SubShader Tags

1.Rendering Order - Queue tag 

    unity为了解决渲染顺序的问题,提供了渲染队列,unity内部使用整数索引表示每个渲染队列,索引越小越先渲染

unity提前定义的5个渲染队列

   名称

队列索引号

描述

Background

1000

最先渲染,通常绘制作为背景的物体,如天空盒

Geometry 

2000

默认的队列,大部分不透明的物体使用这个队列

AlphaTest

2450

需要Alpha Test的物体使用此队列,单独处理是因为处理完不透明物体后进行alpha测试更高效

Transparent

3000

这个渲染队列是在Geometry AlphaTest之后按从后往前的顺序渲染的。任何alpha混合(即着色器不写入深度缓冲)应该在这里(玻璃,粒子特效等)。

Overlay 

4000

这个渲染队列用于一些叠加效果。最后渲染的东西应该在这里(比如镜头光斑,后处理)。

    使用示例:

Shader "Transparent Queue Example"
{
     SubShader
     {
        Tags { "Queue" = "Transparent" }
        Pass
        {
            // rest of the shader body...
        }
    }
}

如果需要渲染的物体在这些队列之间,可以使用:

Tags { "Queue" = "Geometry+1" }

2.RenderType tag

RenderType标签将着色器分类为若干预定义组,例如是一个不透明的着色器,或alpha测试的着色器等。被用于着色器替换,或者在某些情况下用于生成相机的深度纹理。

所有Unity 内置的着色器,都设置了一个RenderType类型,便于渲染时的着色器替换。

内置的RenderType类型有:

built-in Render type

类型

描述

Opaque

用于大多数着色器(法线着色器、自发光着色器、反射着色器以及地形的着色器)。

Transparent

用于半透明着色器(透明着色器、粒子着色器、字体着色器、地形额外通道的着色器)。

TransparentCutout

 蒙皮透明着色器(Transparent Cutout,两个通道的植被着色器)。

Background

天空盒着色器。

Overlay

光晕着色器、闪光着色器。

TreeOpaque

 地形引擎中的树皮。

TreeTransparentCutout

地形引擎中的树叶。

TreeBillboard

地形引擎中的广告牌树。

Grass

地形引擎中的草。

GrassBillboard

地形引擎何中的广告牌草。

3.DisableBatching tag

    一些着色器(主要是对象空间顶点变形的着色器)在使用绘制调用批处理时不起作用——这是因为批处理将所有几何图形转换为世界空间,因此“对象空间”丢失了。可以使用DisableBatching标记来表明这一点。

DisableBatching

Value

描述

“True” 

对于使用此属性的shader 总是不合批

“False”

默认值,总是合批

“LODFading”

当LOD衰减激活时,不合批; 大多用于树

4.ForceNoShadowCasting tag

   如果给定了ForceNoShadowCasting标签,并且该标签的值为“True”,那么使用该子着色器呈现的对象将永远不会投射阴影。这是非常有用的,当你对透明对象使用着色器替换的时候,如果想要这个物体不需要产生阴影,就用这个。半透明物体渲染如果不需要阴影就加上标签。

5.IgnoreProjector tag

    如果IgnoreProjector 标签是给定的,并且有一个“True”的值,那么使用这个着色器的对象将不会受到投影的影响。这在半透明物体上很有用,因为没有好的方法让投影影响它们。这个特性往往那个用在GUI上。程序默认“IgnoreProjector”=“Flase”。

6.CanUseSpriteAtlas tag

    如果着色器用于精灵,当它们放到atlases时,将CanUseSpriteAtlas标签设置为“False”,就无法使用了)。

7.PreviewType tag

    PreviewType指示材质检查器预览应该如何显示材质。默认情况下,材质显示为球体,但PreviewType也可以设置为“Plane”(将显示为2D)或“Skybox” 将显示为skybox)。

 

ShaderLab: Pass Tags

1.LightMode tag

    光照的渲染路径,如果我们需要跟光源打交道,我们需要为每个pass制定它使用的渲染路径,这样shader 的光照计算才能被正常执行。

LightMode标签支持的渲染路径设置选项

标签

描述

Always

不管使用哪种渲染路径总是被渲染

ForwardBase

用于向前渲染,该pass会计算环境光,平行光, 逐顶点/SH光源和lightmaps

ForwardAdd

用于向前渲染,该pass会计算额外的逐像素光源,每个pass对应一个光源

Deferred

用于延迟渲染,改pass会渲染G-buff

ShadowCaster

把物体的深度信息渲染到阴影映射纹理或者一张深度纹理中

MotionVectors

通常计算每个物体的运动向量

PrepassBase

用于遗留的延迟光照,渲染法线和高光反射的指数部分。

PrepassFinal

用于遗留的延迟光照,通过合并纹理,光照,自发光得到最后的颜色

Vertex

用于遗留的顶点光照渲染,当对象没有光照映射时;所有顶点光照都被应用。

VertexLMRGBM

用于遗留的顶点光照渲染,当对象被光照映射时;在lightmap编码为RGBM (PC && console)的平台上。

VertexLM

用于遗留的顶点光照渲染,对象被光照映射时;在lightmap是double-LDR编码的平台(mobile )上。

   当指定了shader 的这些标签以后,我们可以在project Setting -> player -> Other Setting  -> rendering Path中指定项目所需要的渲染路径,也可以在camera选中该camera需要的渲染路径。 

2.PassFlags tag

    pass可以指定渲染管线是怎么样传递数据给它的,这是通过使用PassFlags标记完成的,它的值是用空格分隔的标志名称。目前支持的标志是:

OnlyDirectional:当在ForwardBase pass类型中使用时,这个标志使得只有主方向光和环境光探测数据被传递到着色器中。这意味着不重要的光的数据不被传递到顶点光或球面谐波着色器变量。

3.RequireOptions tag

    一个pass可以表明它只应该在满足一些外部条件时才被渲染。这是通过使用RequireOptions标记完成的,它的值是一个由空格分隔的选项组成的字符串。目前Unity支持的选项有:

SoftVegetation:只有在高质量窗口中打开SoftVegetation时才渲染这个pass。

 

Own tags

    除了unity内置的tags以外,我们可以定义自己的tags,并且使用Meterial.GetTag() function 查询它们.

函数声明:

public string GetTag(string tag, bool searchFallbacks);

public string GetTag(string tag, bool searchFallbacks, string defaultValue);
  • 如果材质的shader没有定义名为tag的标签,则返回defaultValue
  • 如果searchFallbacks 为 true,将会查询查询该shader下所有的subshaders 跟 fallbacks,如果为false,则只查询当前使用的subshader,

    使用GetTag而不通过回退进行搜索,这使得检测当前使用的子着色器成为可能:为每个子着色器添加一个具有不同值的自定义标记,并在运行时查询该值。例如,Unity water使用这个功能来检测着色器何时回到非反射模式,并在这种情况下关闭反射相机。

using UnityEngine;

public class Example : MonoBehaviour
{
    // Attach this to a gameObject that has a renderer.

    string materialTag = "RenderType";

    void Start()
    {
        Renderer rend = GetComponent<Renderer>();
        string result = rend.material.GetTag(materialTag, true, "Nothing");

        if (result == "Nothing")
        {
            Debug.LogError(materialTag + " not found in " + rend.material.shader.name);
        }
        else
        {
            Debug.Log("Tag found!, its value: " + result);
        }
    }
}

 

参考:

https://docs.unity3d.com/Manual/SL-SubShaderTags.html

https://docs.unity3d.com/Manual/SL-PassTags.html