使用multi_compile编译Shader的多个版本

一、新建一个Shader和一个Material

Shader "Custom/Multi_Compile" {
	SubShader {
		Pass {
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma multi_compile MY_multi_1 MY_multi_2 //告诉Unity编译两个不同版本的Shader
		#include "UnityCG.cginc"
		struct vertOut {
			float4 pos:SV_POSITION;
		};
		vertOut vert(appdata_base v)
		{
			vertOut o;
			o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
			return o;
		}
		float4 frag(vertOut i):COLOR
		{
			float4 c = float4(0, 0, 0, 0);
			#ifdef MY_multi_1
			c = float4(0, 1, 0, 0);//输出绿色
			#endif
			#ifdef MY_multi_2
			c = float4(0, 0, 1, 0);//输出蓝色
			#endif
			return c;
		}
		ENDCG
		}
	} 
	FallBack "Diffuse"
}

二、新建个Cube, 挂上脚本Multi_Compile.cs

using UnityEngine;
using System.Collections;
 
public class Multi_Compile : MonoBehaviour {
 
	public bool multi_1;
	// Use this for initialization
	void Start () {
		if (multi_1) {
			Shader.EnableKeyword ("MY_multi_1");
			Shader.DisableKeyword ("MY_multi_2");
		} else {
			Shader.EnableKeyword ("MY_multi_2");
			Shader.DisableKeyword ("MY_multi_1");
		}
	}
}

运行效果,当multi_1=true时:

使用multi_compile编译Shader的多个版本_第1张图片

运行效果,当multi_1=false时:

 

也可以只创建一个关键字,这时候就需要使用__来代替另一个:

#pragma __ TEST_KEY_ON  

这样依然会生成两个shader变体,一个什么都没定义,另外一个定义了TEST_KEY_ON。

 

除了multi_compile之外,还有另外一个类似的指令shader_feature,唯一的区别在于shader_feature不会将不用的shader变体添加到程序中去。shader_feature更适用于材质的关键字,而multi_compile更适用于代码设置的全局关键字。

示例:

#pragma shader_feature TEST_STUFF 

Unity自身还内建一些multi_compile的快捷写法:

multi_compile_fwdbase:为基本前向渲染通道编译多个变体,不同的变体可能需要处理不同的光照贴图类型,或者一些使用了主平行光的阴影,而另一些禁用了。(参考Unity渲染管线)

multi_compile_fwdadd:为附加前向渲染通道编译多个变体,不同的变体可能需要处理不同类型的光源——平行光、聚光灯或者点光源,亦或者它们附带cookie纹理的版本。

multi_compile_fwdadd_fullshadows:同上,不过包含了可以让光源拥有实时阴影的功能。

multi_complie_fog:为处理不同的雾效类型(off/linear/exp/exp2)扩展了多个变体。

 

大部分内建快捷写法会导致许多shader变体,如果某些不需要使用,那么可以使用#pragma skip_variants来忽略它们。

#pragma multi_compile_fwdadd  
// will make all variants containing  
// "POINT" or "POINT_COOKIE" be skipped  
#pragma skip_variants POINT POINT_COOKIE

 

你可能感兴趣的:(Unity)