Unity Shader multi_compile&shader_feature 变体

变体相当于条件判断,当然简单的数值判断可以用step直接代替,这个不提

但是if条件判断对于Shader来说不是一个有效率的方法,为什么说if不好呢?因为GPU是并行计算的,保证一样的执行顺序是有利于GPU的。而当你使用if时,同一段代码的运行顺序与时间就会随着情况的不同而发生变化,这是非常不适合并行计算的。


 PS:这套理论貌似在现在的GPU上不适合了,step甚至有时候会比if费


 

而变体通过Define可以做到,它的原理就是在编译时自动产生多种Shader的变体,根据你在Shader里Define的数量,就会产生多少数量的Shader。再根据你开启哪個Define的功能來运行对应的Shader。

multi_compile 后面的叫Keyword,Keyword的数量是有限制的,最多是256個,但是Unity本身已经预设了不少,所以使用要特別注意数量上限。

Keyword默认第一个开启,下面是一个简单的测试

#pragma multi_compile COLOR_A COLOR_B
 fixed4 frag (v2f i) : SV_Target
            { 
				fixed4 col;
				#ifdef COLOR_A
                col = _ColorA;
                #elif COLOR_B
			    col = _ColorB;
				#endif
                return col;
            }

 

如果换一下 Keyword位置

#pragma multi_compile COLOR_B COLOR_A

 

当然,也可以用脚本控制

Material.EnableKeyword("COLOR_B");
Material.DisableKeyword("COLOR_B");

shader_feature是multi_compile的一个子集。 但是shader_feature是在材质球面板就決定好了要使用的变体,未使用的会在编译时舍去

看一下unity 自带的材质就懂了

MaterialPropertyDrawer 相当于脚本里的属性标签

用Toggle

[Toggle] _Color("ColorA ? ", Float) = 0

#pragma multi_compile __ _COLOR_ON
或者#pragma shader_feature _COLOR_ON


fixed4 frag (v2f i) : SV_Target
            { 
				fixed4 col;
				#ifdef _COLOR_ON
                col = _ColorA;
                #else
			    col = _ColorB;
				#endif
                return col;
            }

如果标签内不指定Keyword的名称,就按变数名大写 + _ON命名

 用KeywordEnum

[KeywordEnum(A,B)] _Color("ColorA ? ", Float) = 0
#pragma multi_compile _COLOR_A _COLOR_B
或者#pragma shader_feature _COLOR_A _COLOR_B

fixed4 col;
#ifdef _COLOR_A
col = _ColorA;
#else
col = _ColorB;
#endif
return col;

 其他还有很多细节,可以直接去看官方文档,就不说了。。

真的很有用啦这个东西

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值