一、ShaderLab 整体框架
hlsl
Shader "Shader路径/Shader名称" { // 1. 属性定义块(可选) Properties { ... } // 2. 自定义编辑器指令(可选) CustomEditor "编辑器类名" // 3. Fallback 回退(可选) Fallback "回退Shader" // 或 Fallback Off // 4. 子着色器(必需,至少一个) SubShader { // 可以有多个SubShader } // 可以有多个SubShader用于不同平台 SubShader { // 针对低端设备的简化版本 } }二、Properties 属性块详解
2.1 属性基本语法
hlsl
Properties { // 格式:属性名 ("显示名称", 类型) = 默认值 // 数值类型 _IntValue ("整型", Int) = 1 _FloatValue ("浮点数", Float) = 1.5 _RangeValue ("范围值", Range(0.0, 1.0)) = 0.5 // 颜色和向量 _Color ("颜色", Color) = (1, 1, 1, 1) _Vector ("四维向量", Vector) = (0, 0, 0, 0) // 纹理 _MainTex ("主纹理", 2D) = "white" {} _NormalMap ("法线贴图", 2D) = "bump" {} // bump是特殊默认值 _CubeMap ("立方体贴图", Cube) = "" {} _3DTex ("3D纹理", 3D) = "black" {} // 特殊属性 [Toggle] _UseEffect ("启用特效", Float) = 0 [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("混合源", Float) = 1 [Header(分组标题)] [Space(20)] // 间距 }2.2 默认纹理值
hlsl
_MainTex ("Texture", 2D) = "white" {} // 白色 _CubeTex ("Cubemap", Cube) = "" {} // 空 _Normal ("Normal", 2D) = "bump" {} // 法线凹凸 _3DTex ("3D Texture", 3D) = "black" {} // 黑色 _DecalTex ("Decal", 2D) = "red" {} // 红色 _DetailTex ("Detail", 2D) = "gray" {} // 灰色2.3 属性修饰器
hlsl
Properties { // HDR颜色 [HDR] _HDRColor ("HDR颜色", Color) = (1,1,1,1) // 在Gamma和Linear空间之间切换 [Gamma] _GammaValue ("Gamma值", Float) = 1.0 // 无符号整型 [IntRange] _IntRange ("整型范围", Range(0, 255)) = 128 // 向量分量 [Vector2] _Vec2 ("二维向量", Vector) = (0,0,0,0) [Vector3] _Vec3 ("三维向量", Vector) = (0,0,0,0) // 关键字切换 [KeywordEnum(Off, On, Blur)] _EffectMode ("特效模式", Float) = 0 // 功率值 [PowerSlider(3.0)] _PowerValue ("功率值", Range(0.01, 1)) = 0.5 // 分组 [Header(光照设置)] [Space(10)] _Glossiness ("光泽度", Range(0,1)) = 0.5 _Metallic ("金属度", Range(0,1)) = 0.0 }三、SubShader 子着色器详解
3.1 SubShader 基本结构
hlsl
SubShader { // 1. 标签(控制渲染队列、类型等) Tags { "Queue" = "Geometry" "RenderType" = "Opaque" "DisableBatching" = "True" } // 2. 渲染状态(全局) Cull Back ZWrite On ZTest LEqual Blend SrcAlpha OneMinusSrcAlpha // 3. LOD值 LOD 200 // 4. 可共享的代码块(可选) CGINCLUDE // 被所有Pass共享的代码 #include "UnityCG.cginc" ENDCG // 5. Pass块(必需,至少一个) Pass { ... } // 可以有多个Pass Pass { ... } }3.2 SubShader 标签详解
hlsl
Tags { // 渲染队列(重要!控制渲染顺序) // 常用值(数字越小越先渲染): // "Background" = 1000 // 背景 // "Geometry" = 2000 // 不透明物体(默认) // "AlphaTest" = 2450 // Alpha测试 // "Transparent" = 3000 // 半透明 // "Overlay" = 4000 // 覆盖层 "Queue" = "Transparent" // 渲染类型(用于着色器替换和相机深度纹理) // 常用值: // "Opaque" // 不透明 // "Transparent" // 半透明 // "TransparentCutout" // 透明裁剪 // "Background" // 天空盒 // "Overlay" // UI、镜头光晕 "RenderType" = "Transparent" // 禁用动态批处理 "DisableBatching" = "True" // "True"/"False"/"LODFading" // 是否投射阴影 "ForceNoShadowCasting" = "True" // 忽略投影器 "IgnoreProjector" = "True" // 是否为预览着色器 "PreviewType" = "Plane" // "Plane"/"Sphere"/"Cube"/"Skybox" // 是否可以被拾取 "CanUseSpriteAtlas" = "True" // 性能相关 "PerformanceChecks" = "False" }3.3 渲染状态(Render States)
hlsl
// 剔除模式 Cull Back // 剔除背面(默认) Cull Front // 剔除正面 Cull Off // 双面渲染 // 深度测试 ZTest Less // 深度小于当前值通过 ZTest Greater // 深度大于当前值通过 ZTest LEqual // 深度小于等于当前值通过(默认) ZTest GEqual // 深度大于等于当前值通过 ZTest Equal // 深度等于当前值通过 ZTest NotEqual // 深度不等于当前值通过 ZTest Always // 总是通过 // 深度写入 ZWrite On // 写入深度缓冲(默认) ZWrite Off // 不写入深度缓冲 // 混合模式 Blend SrcAlpha OneMinusSrcAlpha // 传统透明混合 Blend One One // 加法混合 Blend DstColor Zero // 乘法混合 Blend OneMinusDstColor One // 软加法 Blend SrcAlpha One // 预乘Alpha混合 // Alpha混合 AlphaToMask On // 开启Alpha-to-Coverage // 模板测试 Stencil { Ref 1 Comp Always Pass Replace Fail Keep ZFail Keep } // 颜色通道掩码 ColorMask RGB // 写入RGB通道 ColorMask R // 只写入红色通道 ColorMask 0 // 不写入任何颜色(深度和模板仍可写入) // 裁剪(硬裁剪) Clip { // 动态裁剪 Factor 0.5 Units 0 } // 偏移(解决z-fighting) Offset 0, -1四、Pass 通道详解
4.1 Pass 基本结构
hlsl
Pass { // 1. Pass名称(可选,用于其他Pass引用) Name "FORWARD" // 2. Pass标签 Tags { "LightMode" = "ForwardBase" "PassFlags" = "OnlyDirectional" } // 3. Pass特定的渲染状态 Blend One One ZWrite Off // 4. 着色器代码 CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase // 包含文件 #include "UnityCG.cginc" #include "AutoLight.cginc" #include "UnityPBSLighting.cginc" // 结构体定义 struct appdata { ... }; struct v2f { ... }; // 变量声明 sampler2D _MainTex; // 顶点着色器 v2f vert(appdata v) { ... } // 片元着色器 fixed4 frag(v2f i) : SV_Target { ... } ENDCG }4.2 Pass 标签详解
hlsl
Tags { // 光照模式(重要!) "LightMode" = "ForwardBase" // 前向渲染基础pass "LightMode" = "ForwardAdd" // 前向渲染附加光源pass "LightMode" = "Deferred" // 延迟渲染 "LightMode" = "ShadowCaster" // 阴影投射 "LightMode" = "MotionVectors" // 运动向量 "LightMode" = "PrepassBase" // 遗留延迟渲染 "LightMode" = "Always" // 总是渲染 // 渲染路径要求 "RequireOptions" = "SoftVegetation" // 需要软植被 // 其他Pass引用 "Name" = "MainPass" // Pass名称 }4.3 常用Pass类型
hlsl
// 1. 基础Pass Pass { Tags { "LightMode" = "ForwardBase" } // 处理环境光和主方向光 } // 2. 附加光源Pass Pass { Tags { "LightMode" = "ForwardAdd" } Blend One One // 加法混合 ZWrite Off // 不写入深度 } // 3. 阴影投射Pass Pass { Tags { "LightMode" = "ShadowCaster" } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_shadowcaster float4 vert(appdata_base v) : SV_POSITION { return UnityObjectToClipPos(v.vertex); } fixed4 frag() : SV_Target { return 0; } ENDCG } // 4. 深度纹理Pass(用于屏幕空间效果) Pass { Tags { "LightMode" = "DepthOnly" } ColorMask 0 // 不写入颜色 ZWrite On // 只写入深度 }五、CGPROGRAM 代码块详解
5.1 编译指令
hlsl
CGPROGRAM // 编译目标 #pragma target 3.0 // Shader Model 3.0 #pragma target 4.0 // Shader Model 4.0 #pragma target 5.0 // Shader Model 5.0 // 顶点和片元着色器入口 #pragma vertex vert #pragma fragment frag // 表面着色器指令 #pragma surface surf Lambert #pragma surface surf Standard fullforwardshadows // 几何着色器(需要SM 4.0+) #pragma geometry geom // 细分着色器(需要SM 4.6+) #pragma hull hull_program #pragma domain domain_program // 多编译变体 #pragma multi_compile_fwdbase #pragma multi_compile_fwdadd #pragma multi_compile_fog #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON #pragma shader_feature _NORMALMAP #pragma skip_variants POINT_COOKIE DIRECTIONAL_COOKIE // 禁用警告 #pragma disable warning 3205 // 禁用特定警告 // 优化指令 #pragma fragmentoption ARB_precision_hint_fastest ENDCG
5.2 结构体定义
hlsl
// 输入结构体 struct appdata_base { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct appdata_tan // 带切线的输入 { float4 vertex : POSITION; float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; }; // 输出结构体 struct v2f_base { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 worldPos : TEXCOORD1; float3 worldNormal : TEXCOORD2; }; // 复杂输出(支持多光源) struct v2f_forward_base { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 worldPos : TEXCOORD1; float3 worldNormal : TEXCOORD2; float3 worldTangent : TEXCOORD3; float3 worldBitangent : TEXCOORD4; SHADOW_COORDS(5) // 阴影坐标,占用TEXCOORD5 UNITY_FOG_COORDS(6) // 雾坐标,占用TEXCOORD6 #if defined(LIGHTMAP_ON) float2 lightmapUV : TEXCOORD7; #endif };六、Fallback 和 CustomEditor
6.1 Fallback 回退机制
hlsl
// 1. 回退到内置Shader Fallback "VertexLit" Fallback "Diffuse" Fallback "Specular" Fallback "Standard" // Unity标准Shader // 2. 禁用回退 Fallback Off // 3. 自定义回退 Fallback "Custom/MyFallbackShader"
6.2 CustomEditor 自定义编辑器
hlsl
// 关联自定义编辑器脚本 CustomEditor "MyShaderEditor" // 内置编辑器 CustomEditor "StandardShaderGUI" // 标准Shader编辑器 CustomEditor "SimpleShaderGUI" // 简单Shader编辑器
七、完整示例
hlsl
Shader "Custom/AdvancedShaderExample" { Properties { [Header(Main Settings)] [MainColor] _BaseColor ("颜色", Color) = (1,1,1,1) [MainTexture] _MainTex ("纹理", 2D) = "white" {} [Header(Normal Map)] [Normal] _BumpMap ("法线贴图", 2D) = "bump" {} _BumpScale ("法线强度", Range(0, 2)) = 1 [Header(Specular)] _SpecColor ("高光颜色", Color) = (0.5,0.5,0.5,1) _Glossiness ("光泽度", Range(0,1)) = 0.5 [Header(Emission)] [HDR] _EmissionColor ("自发光颜色", Color) = (0,0,0,1) _EmissionMap ("自发光贴图", 2D) = "white" {} [Header(Advanced)] [Toggle(_ALPHATEST_ON)] _AlphaTest ("启用Alpha测试", Float) = 0 _Cutoff ("Alpha阈值", Range(0,1)) = 0.5 [Enum(UnityEngine.Rendering.CullMode)] _Cull ("剔除模式", Float) = 2 } SubShader { Tags { "RenderType" = "Opaque" "Queue" = "Geometry" "RenderPipeline" = "UniversalPipeline" } LOD 300 // 共享代码 HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" ENDHLSL Pass { Name "ForwardLit" Tags { "LightMode" = "UniversalForward" } Cull [_Cull] ZWrite On ZTest LEqual HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile _ _MAIN_LIGHT_SHADOWS #pragma multi_compile _ _ADDITIONAL_LIGHTS struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float2 texcoord : TEXCOORD0; }; struct Varyings { float4 positionHCS : SV_POSITION; float2 uv : TEXCOORD0; float3 normalWS : TEXCOORD1; }; TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); Varyings vert(Attributes input) { Varyings output; VertexPositionInputs positionInputs = GetVertexPositionInputs(input.positionOS.xyz); output.positionHCS = positionInputs.positionCS; output.uv = input.texcoord; output.normalWS = TransformObjectToWorldNormal(input.normalOS); return output; } half4 frag(Varyings input) : SV_Target { half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv); return color; } ENDHLSL } // 阴影Pass Pass { Name "ShadowCaster" Tags { "LightMode" = "ShadowCaster" } ZWrite On ZTest LEqual HLSLPROGRAM #pragma vertex ShadowPassVertex #pragma fragment ShadowPassFragment #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl" ENDHLSL } } Fallback "Universal Render Pipeline/Lit" CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.LitShader" }八、总结
关键点:
Properties:定义材质面板的可调参数
SubShader:针对不同硬件/平台的着色器变体
Tags:控制渲染顺序、类型等元数据
Pass:具体的渲染通道,每个Pass执行一次渲染
Render States:控制GPU渲染状态(混合、深度、剔除等)
Shader Code:HLSL/Cg代码,实际的着色器逻辑
最佳实践:
使用合适的Queue标签确保正确的渲染顺序
为半透明物体设置Transparent渲染类型
为阴影接收物体添加ShadowCasterPass
使用Fallback提供兼容性
合理使用LOD值控制不同硬件的表现
掌握ShaderLab结构是编写高质量Unity Shader的基础,理解每个部分的作用和相互关系至关重要。