Unity Shader标签(Tags)选项
记录学习Unity Shader过程中学到的东西.
1️⃣Queue
在Unity Shader中,渲染队列(Queue)控制对象的渲染顺序。以下是常见的渲染队列类型及其用途:
内置渲染队列类型
-
Background (1000)
最早渲染的队列,常用于天空盒等背景元素。 -
Geometry (2000)
默认队列,用于大多数不透明物体(如地形、建筑、角色模型)。Unity会对该队列的物体进行深度排序和优化。 -
AlphaTest (2450)
用于使用Alpha测试的半透明物体(如栅栏、植被)。这类物体有明确的透明和不透明区域。 -
Transparent (3000)
用于需要透明度混合的物体(如玻璃、粒子效果)。此队列按从后到前的顺序渲染,以确保正确的混合效果。 -
Overlay (4000)
最后渲染的队列,常用于UI元素或全屏效果,确保它们显示在最上层。
自定义队列
你可以通过指定具体数值来创建自定义队列,例如:
SubShader {
Tags { "Queue" = "Geometry+100" } // 在Geometry队列后100的位置渲染
// 其他Shader代码
}
注意事项
- 性能优化:合理使用队列可以避免不必要的Overdraw。
- 透明物体:使用
Transparent
队列时,需确保物体的几何结构简单且已按距离排序。 - 渲染顺序冲突:相邻队列的物体会按提交顺序渲染,可能导致意外的遮挡问题,需谨慎调整。
这些队列类型覆盖了Unity中大多数渲染需求,合理配置可确保场景正确显示。
2️⃣RenderType
在Unity Shader中,RenderType是一个重要的标签,用于将Shader分类到特定的渲染类型中。这有助于Unity在特定场景(如延迟渲染、光照贴图、着色器替换)中正确处理材质。以下是RenderType的主要作用和常见类型:
RenderType的作用
-
着色器替换(Shader Replacement)
通过指定RenderType,可在运行时替换特定类型的Shader(例如只渲染所有不透明物体或所有透明物体)。 -
光照模式适配
帮助Unity识别Shader是否支持特定光照模式(如前向渲染、延迟渲染)。 -
特殊效果处理
例如在使用雾效、全局光照(GI)或后处理时,Unity会根据RenderType做出不同处理。
常见RenderType标签值
以下是Unity内置的主要RenderType及其用途:
1. Opaque
- 用途:用于不透明物体(如地形、金属、石头)。
- 特点:默认使用前向渲染,支持光照贴图和延迟渲染。
- 示例:
Tags { "RenderType" = "Opaque" }
2. Transparent
- 用途:用于需要透明度混合的物体(如玻璃、粒子效果)。
- 特点:不支持延迟渲染,依赖于渲染队列(通常为
Queue=Transparent
)。 - 示例:
Tags { "RenderType" = "Transparent" "Queue" = "Transparent" }
3. TransparentCutout
- 用途:用于使用Alpha测试的半透明物体(如栅栏、植被)。
- 特点:支持光照贴图和延迟渲染,但需使用
ZWrite On
。 - 示例:
Tags { "RenderType" = "TransparentCutout" "Queue" = "AlphaTest" }
4. Background
- 用途:用于背景元素(如天空盒)。
- 特点:通常在渲染队列的早期(
Queue=Background
)渲染。 - 示例:
Tags { "RenderType" = "Background" "Queue" = "Background" }
5. Overlay
- 用途:用于UI或覆盖效果(如屏幕特效)。
- 特点:通常在渲染队列的最后(
Queue=Overlay
)渲染。 - 示例:
Tags { "RenderType" = "Overlay" "Queue" = "Overlay" }
6. TreeOpaque / TreeTransparentCutout / TreeBillboard
- 用途:专用于地形树木系统的RenderType。
- 特点:与Unity的树烘焙和动画系统协同工作。
7. Grass / GrassBillboard
- 用途:专用于地形草皮系统的RenderType。
- 特点:优化了草的渲染和碰撞。
自定义RenderType
你可以定义自己的RenderType,但通常需要与内置类型配合使用。例如:
Tags { "RenderType" = "CustomType" }
自定义类型在着色器替换时非常有用,但需确保在替换Shader中正确处理。
RenderType vs Queue
- RenderType:分类Shader的功能类型(如不透明、透明)。
- Queue:控制具体的渲染顺序(如
Geometry
、Transparent
队列)。
两者通常结合使用,例如:
SubShader {
Tags {
"RenderType" = "TransparentCutout"
"Queue" = "AlphaTest"
}
// 其他Shader代码
}
最佳实践
- 遵循Unity规范:优先使用内置RenderType,确保与引擎功能兼容。
- 避免重复定义:除非必要,不要创建新的RenderType。
- 性能考虑:透明物体(RenderType=Transparent)会禁用延迟渲染,可能影响性能。
通过合理设置RenderType和Queue,可确保Shader在各种场景下正确渲染,并充分利用Unity的优化机制。
3️⃣DisableBatching
在Unity Shader中,DisableBatching是一个重要的标签,用于控制GPU实例化(GPU Instancing)和批处理(Batching)的行为。以下是其作用、常见用法和注意事项:
DisableBatching的作用
批处理是Unity优化渲染性能的重要手段,通过合并多个网格(Mesh)减少Draw Call。但某些情况下,批处理会破坏Shader的功能,此时需要禁用它。
DisableBatching标签有三种取值:
- True:完全禁用批处理(包括静态批处理和动态批处理)。
- False:不禁用批处理(默认值)。
- LODFading:仅在使用LOD淡入淡出时禁用批处理(针对Unity的LOD系统)。
何时需要禁用批处理?
1. 使用模型空间坐标
若Shader依赖模型空间坐标(如_World2Object
矩阵),批处理会导致多个物体共用同一组坐标,造成渲染错误。
示例场景:
- 顶点动画(如布料、草随风摆动)。
- 基于模型中心的特效(如武器发光)。
Tags { "DisableBatching" = "True" }
// 依赖模型空间坐标的顶点着色器
v2f vert(appdata v) {
v.vertex.xyz += sin(_Time.y) * 0.1; // 随时间摆动(依赖模型空间)
// ...
}
2. 使用多Pass Shader
多Pass Shader在批处理后可能导致渲染顺序异常。
示例场景:
- 双面渲染(一个Pass渲染正面,另一个Pass渲染背面)。
- 复杂的后处理效果。
Tags { "DisableBatching" = "True" }
Pass {
// 第一个Pass渲染正面
}
Pass {
// 第二个Pass渲染背面
}
3. 使用GPU Instancing但需要实例ID
若Shader需要通过UNITY_VERTEX_INPUT_INSTANCE_ID
获取实例ID(如为每个实例分配不同颜色),则必须禁用普通批处理,改用GPU Instancing。
Tags { "DisableBatching" = "True" } // 禁用普通批处理
#pragma multi_compile_instancing // 启用GPU Instancing
struct appdata {
float4 vertex : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID // 声明实例ID
};
DisableBatching与性能
-
禁用批处理的代价:
禁用批处理会增加Draw Call,可能降低性能。因此,应仅在必要时使用,并优先优化Shader逻辑。 -
替代方案:
- GPU Instancing:若Shader支持,可通过
#pragma multi_compile_instancing
启用GPU Instancing,它允许在批处理的同时保留实例独立性。 - 静态批处理:对于不移动的物体,Unity的静态批处理(Static Batching)可能不受DisableBatching影响。
- GPU Instancing:若Shader支持,可通过
常见应用场景
1. 顶点动画Shader
SubShader {
Tags { "DisableBatching" = "True" }
Pass {
// 顶点动画代码(如草摆动、旗帜飘动)
}
}
2. 多Pass透明度Shader
SubShader {
Tags {
"DisableBatching" = "True"
"Queue" = "Transparent"
}
Pass {
// 渲染正面
}
Pass {
// 渲染背面
}
}
3. 基于实例ID的着色
SubShader {
Tags { "DisableBatching" = "True" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
struct appdata {
float4 vertex : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
UNITY_INSTANCING_BUFFER_END(Props)
v2f vert(appdata v) {
UNITY_SETUP_INSTANCE_ID(v);
float4 color = UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
// 使用实例ID获取不同颜色
// ...
}
ENDCG
}
最佳实践
- 仅在必要时禁用:优先调整Shader逻辑以支持批处理。
- 使用GPU Instancing:若需要实例独立性,优先启用GPU Instancing而非完全禁用批处理。
- 性能测试:禁用批处理后,使用Profiler检查Draw Call数量和渲染性能。
通过合理使用DisableBatching标签,可确保Shader功能正确的同时,尽可能减少性能开销。
4️⃣ForceNoShadowCasting
在Unity Shader中,ForceNoShadowCasting是一个用于控制阴影投射行为的标签。通过设置该标签,可以强制指定的物体不投射阴影,即使在光源设置中启用了阴影投射。以下是其作用、用法和注意事项:
ForceNoShadowCasting的作用
该标签的主要用途是:
- 强制禁用阴影投射:无论材质或光源如何设置,带有此标签的物体都不会投射阴影。
- 优化性能:对于不需要投射阴影的物体(如UI元素、粒子效果),禁用阴影投射可以减少计算开销。
- 解决阴影异常:某些特殊Shader(如使用复杂顶点动画的Shader)可能导致阴影计算错误,此时可禁用阴影投射。
标签语法
在SubShader中添加标签:
SubShader {
Tags { "ForceNoShadowCasting" = "True" }
// 其他Shader代码
}
- True:强制禁用阴影投射。
- False(默认):使用Unity的默认阴影投射规则。
应用场景
1. 不应该投射阴影的物体
// 粒子效果Shader
SubShader {
Tags {
"Queue" = "Transparent"
"ForceNoShadowCasting" = "True"
}
// 粒子渲染代码
}
2. UI元素或覆盖层
// UI Shader
SubShader {
Tags {
"Queue" = "Overlay"
"ForceNoShadowCasting" = "True"
}
// UI渲染代码
}
3. 动态物体的性能优化
对于频繁移动或变化的物体(如角色、特效),禁用阴影投射可以显著提升性能:
// 角色Shader(禁用阴影以优化性能)
SubShader {
Tags { "ForceNoShadowCasting" = "True" }
// 角色渲染代码
}
与其他阴影相关标签的区别
标签 | 作用 |
---|---|
ForceNoShadowCasting | 强制禁用阴影投射,无论光源和材质设置如何。 |
ShadowCaster Pass | 自定义阴影投射的渲染逻辑(如使用不同的Shader)。 |
ReceiveShadows | 控制物体是否接收阴影(而非投射阴影)。 |
注意事项
-
性能权衡:
- 禁用阴影投射可减少Draw Call和GPU计算,但可能影响场景真实感。
- 对于静态物体,建议使用烘焙阴影而非动态阴影。
-
阴影接收:
ForceNoShadowCasting仅影响阴影投射,物体仍可接收其他物体的阴影。若需同时禁用阴影接收,可配合使用:Tags { "ForceNoShadowCasting" = "True" "ReceiveShadows" = "False" }
-
Shader替换:
在使用Shader替换(Shader Replacement)时,ForceNoShadowCasting标签可能被忽略,需在替换Shader中显式设置。
最佳实践
- 仅对必要物体禁用:优先为不影响视觉效果的物体(如UI、粒子)禁用阴影投射。
- 结合烘焙阴影:对于静态场景元素,使用光照贴图(Lightmap)和烘焙阴影可获得更好的性能。
- 性能测试:使用Unity Profiler检查阴影计算对性能的影响,针对性地优化。
通过合理使用ForceNoShadowCasting标签,可以在保证视觉效果的同时提升渲染性能,尤其在移动设备或性能敏感的场景中尤为重要。
5️⃣IgnoreProjector
在Unity Shader中,IgnoreProjector是一个用于控制Shader是否受Projector(投影器)影响的标签。通过设置该标签,可以让物体忽略场景中的投影器效果,保持自身原有渲染。以下是其作用、用法和注意事项:
IgnoreProjector的作用
Projector是Unity中用于投射纹理或效果的组件(如阴影、血迹、激光等)。但某些情况下,你可能希望特定物体不受投影器影响:
- 视觉一致性:确保物体渲染不受外部投影干扰(如UI元素、特效)。
- 性能优化:减少不必要的投影计算,提升性能。
- 技术限制:某些复杂Shader可能与投影器不兼容。
标签语法
在SubShader中添加标签:
SubShader {
Tags { "IgnoreProjector" = "True" }
// 其他Shader代码
}
- True:物体将忽略所有投影器效果。
- False(默认):物体将正常受投影器影响。
应用场景
1. UI元素或覆盖层
// UI Shader
SubShader {
Tags {
"Queue" = "Overlay"
"IgnoreProjector" = "True"
}
// UI渲染代码
}
2. 特效或粒子系统
// 粒子Shader
SubShader {
Tags {
"Queue" = "Transparent"
"IgnoreProjector" = "True"
}
// 粒子渲染代码
}
3. 已包含复杂效果的Shader
对于使用自定义光照模型或复杂顶点动画的Shader,投影器可能导致渲染异常:
// 自定义光照Shader
SubShader {
Tags { "IgnoreProjector" = "True" }
// 复杂光照计算代码
}
与其他标签的协同使用
标签 | 作用 |
---|---|
IgnoreProjector | 忽略投影器效果。 |
ForceNoShadowCasting | 禁用阴影投射。 |
RenderType | 控制Shader在特定场景(如延迟渲染)中的行为。 |
注意事项
-
投影器类型限制:
IgnoreProjector仅影响Unity的内置Projector组件,对基于脚本或后处理的自定义投影效果无效。 -
性能影响:
虽然忽略投影器可减少计算,但现代GPU处理投影器的开销通常较小,优化时需权衡。 -
Shader替换:
在使用Shader替换(Shader Replacement)时,需确保替换Shader也包含IgnoreProjector标签。
最佳实践
- 仅对必要物体启用:优先为UI、特效等不需要投影效果的物体设置此标签。
- 测试视觉效果:禁用投影器可能影响场景真实感,需确保效果符合预期。
- 结合其他优化:与ForceNoShadowCasting、ReceiveShadows等标签配合使用,进一步减少渲染开销。
通过合理使用IgnoreProjector标签,可以确保特定物体的渲染效果不受投影器干扰,同时优化性能。
6️⃣CanUseSpriteAtlas
在Unity Shader中,CanUseSpriteAtlas 是一个与精灵图集(Sprite Atlas)相关的标签,主要用于控制Sprite是否可以从精灵图集中获取纹理数据。以下是其具体作用和用法:
CanUseSpriteAtlas的作用
精灵图集是Unity中优化2D渲染性能的重要工具,它将多个Sprite打包到一个或多个纹理中,减少Draw Call。CanUseSpriteAtlas 标签的核心作用是:
-
允许Sprite使用图集
当标签设置为 "True" 时,Shader告诉Unity该Sprite可以从精灵图集中获取纹理数据。这是精灵图集正常工作的必要条件。 -
兼容Sprite Packer
在旧版Unity(2017及之前)中,该标签用于与Sprite Packer系统配合,确保Sprite在打包后仍能正确渲染。 -
控制Shader替换行为
在使用Shader替换(Shader Replacement)时,该标签可帮助Unity判断哪些Shader适用于精灵图集渲染。
标签语法
在Shader的SubShader中添加标签:
SubShader {
Tags { "CanUseSpriteAtlas" = "True" }
// 其他Shader代码
}
- "True":允许Sprite使用精灵图集。
- "False":禁用精灵图集支持,Sprite将始终使用单独的纹理。
应用场景
1. 精灵图集渲染
所有需要从精灵图集获取纹理的Sprite Shader都应添加此标签:
// 精灵Shader示例
SubShader {
Tags {
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"CanUseSpriteAtlas" = "True"
}
// 渲染精灵的Pass
}
2. 自定义Sprite Shader
当创建自定义Sprite Shader时,必须添加此标签以确保与精灵图集兼容:
// 自定义精灵着色器
SubShader {
Tags { "CanUseSpriteAtlas" = "True" }
Pass {
// 自定义渲染逻辑(如顶点动画、特殊效果)
}
}
3. 旧版Unity兼容性
在Unity 2017及更早版本中,该标签对Sprite Packer系统至关重要:
// 兼容旧版Sprite Packer的Shader
SubShader {
Tags { "CanUseSpriteAtlas" = "True" }
// 旧版渲染逻辑
}
注意事项
-
Unity版本差异
- 在Unity 2018及以后,精灵图集系统(Sprite Atlas)已取代旧版Sprite Packer,但该标签仍需保留以确保兼容性。
- 若Shader不打算用于精灵图集(如仅渲染单个Sprite),可将标签设为 "False"。
-
与其他标签的协同
通常需与以下标签共同使用:Tags { "RenderType" = "Transparent" "Queue" = "Transparent" "CanUseSpriteAtlas" = "True" }
-
性能影响
使用精灵图集可显著减少Draw Call,提升2D渲染性能。若禁用该标签,Sprite将无法从图集中受益。
最佳实践
-
始终为精灵Shader添加此标签
除非明确不需要使用精灵图集,否则所有Sprite Shader都应设置"CanUseSpriteAtlas" = "True"
。 -
结合SpriteAtlas API
在脚本中可通过SpriteAtlas
API 动态管理精灵图集:// C#示例:加载精灵图集 SpriteAtlas atlas = Resources.Load<SpriteAtlas>("MySpriteAtlas"); Sprite sprite = atlas.GetSprite("MySprite");
-
测试与优化
使用Profiler检查精灵渲染的Draw Call数量,确保精灵图集正常工作。
通过合理使用 CanUseSpriteAtlas 标签,可确保Sprite在精灵图集中正确渲染,提升2D游戏的性能和兼容性。
7️⃣PreviewType
在Unity Shader中,PreviewType 是一个用于控制材质在Inspector面板中预览方式的标签。通过设置该标签,你可以自定义Shader在Unity编辑器中的预览效果,使其更直观地展示材质特性。以下是其作用、用法和常见场景:
PreviewType的作用
-
指定预览几何体
控制Shader在Inspector面板中使用何种模型预览(如球体、立方体、平面等)。 -
自定义预览效果
针对特殊Shader(如地形、UI、粒子),提供更符合其特性的预览方式。 -
优化预览性能
对于复杂Shader,选择简单几何体可减少预览计算开销。
标签语法
在Shader代码中添加:
Shader "Custom/MyShader" {
Properties {
// 属性定义
}
SubShader {
Tags { "PreviewType" = "Sphere" } // 指定预览类型
// 其他Shader代码
}
}
常见PreviewType值
值 | 作用 |
---|---|
Sphere | 使用球体预览(默认值,适合大多数Shader,如标准材质)。 |
Plane | 使用平面预览(适合2D材质、UI元素、广告牌效果)。 |
Cube | 使用立方体预览(适合立方体贴图、反射材质)。 |
Skybox | 使用天空盒预览(适合天空盒Shader)。 |
Mesh | 使用自定义网格预览(需配合 PreviewMesh 标签指定网格路径)。 |
应用场景
1. 2D精灵或UI材质
Shader "Custom/SpriteShader" {
SubShader {
Tags {
"PreviewType" = "Plane" // 使用平面预览,更符合2D材质特性
"RenderType" = "Transparent"
}
// 渲染代码
}
}
2. 立方体贴图或反射材质
Shader "Custom/ReflectionShader" {
SubShader {
Tags {
"PreviewType" = "Cube" // 使用立方体展示六个面的反射效果
}
// 渲染代码
}
}
3. 天空盒Shader
Shader "Custom/SkyboxShader" {
SubShader {
Tags {
"PreviewType" = "Skybox" // 使用天空盒预览
"RenderType" = "Background"
}
// 渲染代码
}
}
4. 自定义网格预览
Shader "Custom/TerrainShader" {
SubShader {
Tags {
"PreviewType" = "Mesh"
"PreviewMesh" = "Assets/Models/TerrainPreview.fbx" // 指定自定义网格
}
// 渲染代码
}
}
与其他预览相关标签的配合
标签 | 作用 |
---|---|
PreviewType | 指定预览几何体类型。 |
PreviewMesh | 当PreviewType为"Mesh"时,指定自定义网格的路径。 |
DisablePreview | 禁用预览(设为"True"时,材质在Inspector中不显示预览)。 |
注意事项
-
性能考虑
- 复杂网格(如自定义PreviewMesh)可能增加预览渲染时间,建议使用简化模型。
-
路径问题
- 使用
PreviewMesh
时,需确保网格路径正确且可被Unity识别。
- 使用
-
版本兼容性
- 部分Unity版本可能对某些PreviewType值支持有限,建议测试后使用。
最佳实践
-
为特殊Shader指定合适类型
- 2D材质 → Plane
- 反射/立方体贴图 → Cube
- 天空盒 → Skybox
- 地形/复杂模型 → 自定义Mesh
-
简化自定义预览网格
自定义PreviewMesh应尽量简单(如低面数模型),避免影响编辑器性能。 -
结合预览属性
在Properties中添加预览相关属性(如预览颜色),提升可视化效果:Properties { _MainTex ("Texture", 2D) = "white" {} [PreviewVisible] _Color ("Preview Color", Color) = (1,1,1,1) // 预览可见的颜色 }
通过合理设置 PreviewType,可以让Shader在Unity编辑器中更直观地展示其效果,提高开发效率。