
什么是 ShaderLab?
ShaderLab 是 Unity 引擎专用的声明式语法,它为开发者提供了一种统一的方式来描述着色器资源的外观和行为。无论你是使用 Surface Shader、Vertex/Fragment Shader 还是 Fixed Function Shader,ShaderLab 都是你编写 Unity Shader 的基础。
核心优势
ShaderLab 屏蔽了不同图形 API(Direct3D、OpenGL、Vulkan、Metal)之间的差异,让开发者专注于着色器逻辑本身。

Properties - 属性定义
Properties 代码块定义了材质面板中可见的可调参数。每个属性都有唯一的名称(带下划线前缀)、显示名称、类型和默认值。
cs
Shader "Custom/ExampleShader" {
Properties {
// 属性名称 ("显示名称", 类型) = 默认值
_Color ("Main Color", Color) = (1, 1, 1, 1)
_MainTex ("Base Texture", 2D) = "white" {}
_NormalMap ("Normal Map", 2D) = "bump" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0
_Cutoff ("Alpha Cutoff", Float) = 0.5
_VectorExample ("Vector", Vector) = (0, 1, 0, 1)
}
// ... SubShader 和其他内容
}
支持的属性类型
Float / Range单精度数值,用于平滑度、金属度等参数
Color / Vector四维向量,Color带颜色拾取器
2D2D纹理采样器,可指定默认值
3D3D纹理,用于体积数据
Cube立方体贴图,用于环境反射
Int整数类型
纹理默认值
常见的纹理默认值:"white"、"black"、"gray"、"bump"、"red"(纯红色纹理)、""(空)。特殊的 "bump" 会生成法线贴图。
SubShader - 子着色器
SubShader 是实际执行渲染指令的代码块。Unity 会从上到下选择第一个被当前显卡支持的 SubShader。你可以在一个 Shader 中定义多个 SubShader,以适配不同性能级别的硬件。
SubShader 基本结构核心
cs
SubShader {
// 标签定义
Tags {
"RenderType" = "Opaque"
"Queue" = "Geometry"
}
// LOD 级别
LOD 200
// 渲染通道
Pass {
CGPROGRAM
// CG/HLSL 代码...
ENDCG
}
}
SubShader Tags
RenderType
分类着色器类型:Opaque、Transparent、Background、Overlay、TreeOpaque 等,用于着色器替换和后期处理。
Queue
渲染队列:Background、Geometry、AlphaTest、Transparent、Overlay。控制物体绘制顺序。
DisableBatching
禁用批处理:"True"、"False"或"LODFading"。某些效果(如顶点动画)需要禁用批处理。
ForceNoShadowCasting
设为 "True" 时,此 SubShader 不会投射阴影。
IgnoreProjector
设为 "True" 时,物体不受 Projector 影响。
LightMode
光照模式标签:Always、ForwardBase、ForwardAdd、Deferred、ShadowCaster 等。
Fallback - 回退机制
Fallback 定义了当所有 SubShader 都不被当前设备支持时,Unity 将使用的备用着色器。这确保了你的着色器在低端硬件上也能正常工作。
cs
// 当没有可用的 SubShader 时,使用内置的 Diffuse 着色器
Fallback "Diffuse"
// 关闭回退功能(不推荐,可能导致物体完全不显示)
Fallback "Off"
// 常见的内置回退着色器
// "Diffuse" - 基础漫反射
// "Specular" - 带高光的漫反射
// "VertexLit" - 最简单的顶点光照
// "Mobile/Diffuse" - 移动端优化版本
最佳实践
始终为自定义着色器设置合理的 Fallback。这不仅保证了向下兼容性,还能让不支持你着色器的物体至少以基本材质形式显示出来。
LOD - 细节层次
LOD (Level of Detail) 系统允许你根据物体与摄像机的距离自动切换不同复杂度的着色器版本。远处的物体使用简化的着色器,近处的物体使用高质量着色器。
cs
Shader "Custom/DetailedShader" {
// Shader 级别的 LOD 限制(可选)
LOD 400
SubShader {
// 这个 SubShader 的 LOD 级别
LOD 300
// 高质量版本 - 法线贴图、高光等
// ...
}
SubShader {
LOD 200
// 中等质量版本
// ...
}
SubShader {
LOD 100
// 低质量简化版本
// ...
}
Fallback "Mobile/Diffuse"
}
常用着色器的 LOD 值
| 内置着色器 | LOD 值 | 说明 |
|---|---|---|
| Standard (Shader Model 3.0) | 300 | PBR 工作流,支持法线贴图 |
| Standard (Shader Model 2.0) | 150 | 降级版 PBR,部分特性被禁用 |
| VertexLit | 100 | 最简单的顶点光照着色器 |
| Mobile/VertexLit | 50 | 移动端优化的极简版本 |
配置全局 LOD
通过 Quality Settings → Maximum LOD Level,你可以控制整个项目使用的最大 LOD 值,无需逐个修改着色器。
高级特性
CustomEditor
自定义材质面板的编辑器界面,让美术和设计师获得更好的工作流程体验。
Dependency
定义着色器属性之间的依赖关系,用于自动更新相关参数。
UsePass
引用其他着色器中的 Pass,避免代码重复。
GrabPass
抓取屏幕内容到纹理中,用于折射、反射等屏幕空间效果。
完整的 ShaderLab 示例
cs
Shader "Custom/PBRWithLOD" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo", 2D) = "white" {}
_BumpMap ("Normal Map", 2D) = "bump" {}
_Metallic ("Metallic", Range(0,1)) = 0
_Glossiness ("Smoothness", Range(0,1)) = 0.5
}
SubShader {
Tags {
"RenderType"="Opaque"
"Queue"="Geometry"
}
LOD 300
Pass {
CGPROGRAM
// 高质量 PBR 实现
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
struct Input {
uv_MainTex;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
// ... 实现代码
}
ENDCG
}
}
SubShader {
LOD 100
// 简化的基础光照版本
}
Fallback "Mobile/Diffuse"
}
总结
ShaderLab 是 Unity 着色器开发的核心,掌握它的语法结构对于创建高质量、可移植的着色器至关重要。
🎯 Properties
定义材质面板参数,让美术师可以可视化调整着色器效果
🔄 SubShader
编写多版本着色器,自动适配不同性能级别的硬件设备
🛡️ Fallback
设置备用着色器,确保在低端设备上也能正常渲染
📏 LOD
根据距离切换细节级别,优化性能并保持视觉质量