#pragma multi_compile_fwdbase是unity内置的用于前向渲染的关键字快捷方式,它包含了前向渲染光照计算需要的大多数关键字,因此会被shader带来很多的变体。

下面这个简单的shader有8个变体:

Shader "James/Texture"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
} SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Geometry" }
LOD Pass
{
Tags { "LightMode"="ForwardBase" }
Lighting Off CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase uniform sampler2D _MainTex;
uniform half4 _MainTex_ST; struct vertexIN_base
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
}; struct v2f_base
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
}; v2f_base vert(vertexIN_base v)
{
v2f_base o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw; return o;
} fixed4 frag(v2f_base i) : COLOR
{
return tex2D(_MainTex, i.uv);
}
ENDCG
}
}
FallBack Off
}

我们来看一下这些变体都有谁:

// Total snippets: 1
// -----------------------------------------
// Snippet #0 platforms ffffffff:
Builtin keywords used: DIRECTIONAL DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON LIGHTMAP_ON LIGHTMAP_SHADOW_MIXING LIGHTPROBE_SH SHADOWS_SCREEN SHADOWS_SHADOWMASK VERTEXLIGHT_ON keyword variants used in scene: DIRECTIONAL
DIRECTIONAL LIGHTPROBE_SH
DIRECTIONAL SHADOWS_SCREEN
DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN
DIRECTIONAL VERTEXLIGHT_ON
DIRECTIONAL LIGHTPROBE_SH VERTEXLIGHT_ON
DIRECTIONAL SHADOWS_SCREEN VERTEXLIGHT_ON
DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN VERTEXLIGHT_ON

然后我们去掉multi_compile_fwdbase,看一下变体的情况:

// Total snippets: 1
// -----------------------------------------
// Snippet #0 platforms ffffffff: keyword variants used in scene: <no keywords defined>

可以看到这个shader就只会生成一个版本。

所以我们在通过shader实现一些效果时,一定要谨慎使用这种内置的快捷方式,它会给shader带来大量的变体,造成量大又不必要的浪费。

05-11 17:03