Version: 2021.1
ShaderLab:定义子着色器
ShaderLab:为子着色器指定 LOD 值

ShaderLab:向子着色器分配标签

本页面包含有关在 ShaderLab 代码中使用 Tags 代码块向子着色器分配标签的信息。

有关定义子着色器的信息,请参阅 ShaderLab:定义子着色器。有关 Shader 对象的工作原理以及 Shader 对象、子着色器与通道之间关系的信息,请参阅 Shader 对象

概述

标签是数据的键/值对。Unity 使用预定义键和值确定如何以及何时使用给定子着色器,也可以使用自定义值创建自己的自定义子着色器标签。可以从 C# 代码访问子着色器标签。

渲染管线兼容性

功能名称 内置渲染管线 通用渲染管线 (URP) 高清渲染管线 (HDRP) 自定义 SRP
ShaderLab:子着色器标签代码块
ShaderLab:RenderPipeline 子着色器标签
ShaderLab:Queue 子着色器标签



注意:在自定义 SRP 中,可以定义自己的渲染顺序并选择是否要使用渲染队列。有关更多信息,请参阅 DrawingSettings 和 SortingCriteria。
ShaderLab:RenderType 子着色器标签
ShaderLab:DisableBatching 子着色器标签
ShaderLab:ForceNoShadowCasting 子着色器标签

这会禁用常规阴影,但是不影响接触阴影。
ShaderLab:CanUseSpriteAtlas 子着色器标签
ShaderLab:PreviewType 子着色器标签

在子着色器中使用 Tags 代码块

在 ShaderLab 中,可以通过将 Tags 代码块置于 SubShader 代码块中来向子着色器分配标签。

请注意,子着色器和通道都使用 Tags 代码块,但其工作方式不同。向通道分配子着色器标签没有效果,反之亦然。区别在于放置 Tags 代码块的位置:

  • 要定义通道标签,请将 Tags 代码块置于 Pass 代码块内部。
  • 要定义子着色器标签,请将 Tags 代码块置于 SubShader 代码块内部,但是在 Pass 代码块外部。

有关向通道分配标签的信息,请参阅向通道分配标签

签名 功能
Tags { “[name1]” = “[value1]” “[name2]” = “[value2]”} 将给定标签应用于子着色器。

可以定义所需数量的标签。

在 C# 代码中使用子着色器标签

可以使用 Material.GetTag API 从 C# 脚本中读取子着色器标签,如下所示:

using UnityEngine;

public class Example : MonoBehaviour
{
    // 将此附加到具有渲染器组件的游戏对象
    string tagName = "ExampleTagName";

    void Start()
    {
        Renderer myRenderer = GetComponent<Renderer>();
        string tagValue = myRenderer.material.GetTag(ExampleTagName, true, "Tag not found");
        Debug.Log(tagValue);
    }
}

RenderPipeline 标签

RenderPipeline 标签向 Unity 告知子着色器是否与通用渲染管线 (URP) 或高清渲染管线 (HDRP) 兼容。

语法和有效值

签名 功能
“RenderPipeline” = “[name]” 向 Unity 告知此子着色器是否与 URP 或 HDRP 兼容。
参数 功能
[name] UniversalRenderPipeline 此子着色器仅与 URP 兼容。
HighDefinitionRenderPipeline 此子着色器仅与 HDRP 兼容。
(任何其他值,或未声明) 此子着色器与 URP 和 HDRP 不兼容。

示例

此示例代码声明子着色器与 URP 兼容:

Shader "ExampleShader" {
    SubShader {
        Tags { "RenderPipeline" = "UniversalRenderPipeline" }
        Pass {
            …
        }
    }
}

Queue 标签

Queue 标签向 Unity 告知要用于它渲染的几何体的渲染队列。渲染队列是确定 Unity 渲染几何体的顺序的因素之一。

语法和有效值

可以通过两种方式使用 Queue 标签:可以告知 Unity 使用命名渲染队列,或是它在命名渲染队列之后渲染的未命名渲染队列。

签名 功能
“Queue” = “[queue name]” 使用命名渲染队列。
“Queue” = “[queue name] + [offset]” 在相对于命名队列的给定偏移处使用未命名队列。

这种用法十分有用的一种示例情况是透明的水,它应该在不透明对象之后绘制,但是在透明对象之前绘制。
签名 功能
[queue name] Background 指定背景渲染队列。
Geometry 指定几何体渲染队列。
AlphaTest 指定 AlphaTest 渲染队列。
Transparent 指定透明渲染队列。
Overlay 指定覆盖渲染队列。
[offset] 整数 指定 Unity 渲染未命名队列处的索引(相对于命名队列)。

将此标签与 C# 代码一起使用

可以使用 Shader.renderQueue 读取 Shader 对象的活动子着色器的 Queue 标签值。

默认情况下,Unity 在 [Queue] 标签指定的渲染队列中渲染几何体。可以基于每种材质覆盖此值。在 Unity 编辑器中,可以通过设置渲染队列属性,在材质 Inspector 中执行此操作。在 C# 脚本中,可以通过使用 Rendering.RenderQueue 枚举设置 Material.renderQueue 的值来执行此操作。

示例

此示例代码创建一个子着色器,它将几何体作为透明渲染队列的一部分进行渲染:

Shader "ExampleShader" {
    SubShader {
        Tags { "Queue" = "Transparent" }
        Pass {
            …
        }
    }
}

此示例代码创建一个子着色器,它在几何体队列之后的未命名队列中渲染几何体。

Shader "ExampleShader" {
    SubShader {
        Tags { "Queue" = "Geometry+1" }
        Pass {
            …
        }
    }
}

RenderType 标签

使用 RenderType 标签可覆盖 Shader 对象的行为。

在内置渲染管线中,可以使用一种称为着色器替换的技术在运行时交换子着色器。此技术的工作方式是标识具有匹配 RenderType 标签值的子着色器。这在某些情况下用于生成摄像机的深度纹理

在基于可编程渲染管线的渲染管线中,可以使用 RenderStateBlock 结构覆盖在 Shader 对象中定义的渲染状态。可以使用 RenderType 标签的值标识要覆盖的子着色器。

语法和有效值

签名 功能
“RenderType” = “[renderType]” 为此子着色器设置 RenderType 值。
签名 功能
[renderType] String 没有为此参数设置值。要标识要替换的任何子着色器的 RenderType 值,请打开其着色器源文件。

Unity 旧版内置着色器的 RenderType 子着色器标签在着色器替换页面上列出。

还可以为自定义子着色器创建自己的值。

将此标签与 C# 代码一起使用

有关内置渲染管线中着色器替换的信息,请参阅着色器替换。有关在可编程渲染管线中使用 RenderStateBlock 的信息,请参阅 ScriptableRenderContext.DrawRenderers 的 API 文档。

示例

此示例代码创建一个 RenderType 值为 TransparentCutout 的子着色器:

Shader "ExampleShader" {
    SubShader {
        Tags { "RenderType" = "TransparentCutout" }
        Pass {
            …
        }
    }
}

ForceNoShadowCasting 标签

ForceNoShadowCasting 标签阻止子着色器中的几何体投射(有时是接收)阴影。确切行为取决于渲染管线和渲染路径。

如果使用着色器替换,但是不希望从其他子着色器继承阴影通道,这可能非常有用。

语法和有效值

签名 功能
“ForceNoShadowCasting” = “[state]” 是否对所有使用此子着色器的几何体阻止阴影投射(有时是接收)。
签名 功能
[state] True Unity 阻止此子着色器中的几何体投射阴影。

在内置渲染管线中,对于前向、旧版顶点光照或旧版延迟渲染路径,Unity 还会阻止此子着色器中的几何体接收阴影。

在 HDRP 中,这不会阻止几何体投射接触阴影。
False Unity 不会阻止此子着色器中的几何体投射或接收阴影。这是默认值。

示例

此示例代码创建一个 ForceNoShadowCasting 值为 True 的子着色器:

Shader "ExampleShader" {
    SubShader {
        Tags { "ForceNoShadowCasting" = "True" }
        Pass {
            …
        }
    }
}

DisableBatching 标签

DisableBatching 子着色器标签阻止 Unity 将动态批处理应用于使用此子着色器的几何体。

这对于执行对象空间操作的着色器程序十分有用。动态批处理会将所有几何体都变换为世界空间,这意味着着色器程序无法再访问对象空间。因此,依赖于对象空间的着色器程序不会正确渲染。为避免此问题,请使用此子着色器标签阻止 Unity 应用动态批处理。

语法和有效值

签名 功能
“DisableBatching” = “[state]” Unity 是否对使用此子着色器的所有几何体阻止动态批处理。
签名 功能
[state] True Unity 对使用此子着色器的几何体阻止动态批处理。
False Unity 不会对使用此子着色器的几何体阻止动态批处理。这是默认值。
LODFading 对于属于 Fade Mode 值不为 None 的 LODGroup 一部分的所有几何体,Unity 会阻止动态批处理。否则,Unity 不会阻止动态批处理。

示例

此示例代码创建一个 DisableBatching 值为 True 的子着色器:

Shader "ExampleShader" {
    SubShader {
        Tags { "DisableBatching" = "True" }
        Pass {
            …
        }
    }
}

IgnoreProjector 标签

在内置渲染管线中,IgnoreProjector 子着色器标签向 Unity 告知几何体是否受投影器影响。这对于排除投影器不兼容的半透明几何体多半很有用。

此标签在其他渲染管线中无效。

语法和有效值

签名 功能
“IgnoreProjector” = “[state]” Unity 在渲染此几何体时是否忽略投影器。
签名 功能
[state] True Unity 在渲染此几何体时忽略投影器。
False Unity 在渲染此几何体时不会忽略投影器。这是默认值。

示例

此示例代码创建一个 IgnoreProjectors 值为 True 的子着色器:

Shader "ExampleShader" {
    SubShader {
        Tags { "IgnoreProjector" = "True" }
        Pass {
            …
        }
    }
}

PreviewType 标签

PreviewType 子着色器 Tag 告知 Unity 编辑器如何在材质 Inspector 中显示使用此子着色器的材质。

语法和有效值

签名 功能
“PreviewType” = “[shape]” Unity 编辑器用于显示使用此子着色器的材质预览的形状。
签名 功能
[shape] 球体 在球体上显示材质。这是默认值。
平面 (Plane) 在平面上显示材质。
Skybox 在天空盒上显示材质。

示例

此示例代码创建一个 PreviewType 值为 Plane 的子着色器:

Shader "ExampleShader" {
    SubShader {
        Tags { "PreviewType" = "Plane" }
        Pass {
            …
        }
    }
}

CanUseSpriteAtlas 标签

在使用 Legacy Sprite Packer 的项目中使用此子着色器标签可警告用户着色器依赖于原始纹理坐标,因此不应将其纹理打包到图集中。

语法和有效值

签名 功能
“CanUseSpriteAtlas” = “[state]” 使用此子着色器的精灵是否与 Legacy Sprite Packer 兼容。
签名 功能
[state] True 使用此子着色器的精灵与 Legacy Sprite Packer 兼容。这是默认值。
False 使用此子着色器的精灵与 Legacy Sprite Packer 不兼容。

CanUseSpriteAtlas 值为 False 的子着色器与带有 Legacy Sprite Packer 打包标签的精灵一起使用时,Unity 会在 Inspector 中显示错误消息。

CanUseSpriteAtlas 标签代码示例

此示例代码创建一个 CanUseSpriteAtlas 值为 False 的子着色器:

Shader "ExampleShader" {
    SubShader {
        Tags { "CanUseSpriteAtlas" = "False" }
        Pass {
            …
        }
    }
}
ShaderLab:定义子着色器
ShaderLab:为子着色器指定 LOD 值