Unity Shader 如何配置宏之二_深扒 多重编译gragma multi_compile

参考资料:

大叔博客提及的多重编译开关

https://blog.csdn.net/qq18052887/article/details/80389506

多重编译入门

https://www.jianshu.com/p/f34d896dde5d

变体多了,发布卡和包体大问题

https://www.jianshu.com/p/08877fb0fceb

(没完全理解,也看了下《天涯明月刀》自制Shader编译和加载的资料,暂时没需要,没深究)

 

之前乱说的

由于真的开始着手,之前头疼的问题,改人家的代码:

之前我会觉得最好的办法是不要用宏,因为看过太多惨剧。

会觉得一是不负责任的“资深”程序员,或者是“初出茅庐”的实习生才会用的

但要是真的想升格为“高级”程序员,宏定义还是必要的

其实真没那么高大上,很多“程序员‘自以为看了2本书,就觉得自己很牛,这里就是要扒开他们的不堪

Unity Shader的案例是这样的

			#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON 

用的时候

#ifndef LIGHTMAP_OFF
				o.uvLM.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
#endif

下面会展开说,就算,只要你只有一点点”程序“经验,应该也能看下去:

这时候,网上大部分都会这么说,有双下划线写法:

//#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON 
//可以这么写,减少宏变量,有个数限制
#pragma multi_compile __ LIGHTMAP_ON 

哥有点lua语言经验,知道下划线 在L编程里能 _替代空变量,这么理解这里的双下划线就容易很多了。。。虽然他们是不同语言

例如 lua遍历可以这么写:

for _,v in pairs(tb) do
--...
end

只是Shader 这里用了双下划线 __替代空的宏定义,lua只是题外话,那的shader的问题来了

multi_compile __ xxx 是什么意思呢

multi_compile  xxx __ 这么写又行不行呢

明显的,作为程序员,我们的直觉告诉我们,这    multi_compile  是一个语法,xxx 和 __ 都是他的参数,有一定的写法,有一定作用的,这不是废话吗??

是有点废,我的意思是:

1.你自然而然就会写空格 ,而且必然是 multi_compile空格[1]空格 [2] 这样的结构(具体公式格式我不会写)

2.少写一个参数应该肯定不行的,这2参数必然是一对的

3.默认会选第一个参数,也就是multi_compile  xxx __ 是绝对不行的。。。。

怎么理解上面这3个规则呢(不需要理解,这是程序员的逻辑)

不理解不重要,先看看测试结果

有一个石头,有点黄昏的光照

#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON 
#ifndef LIGHTMAP_OFF
				fixed3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM.xy));
				finalColor.rgb *= lm;
#endif

写法一,发光

//#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON 
#ifndef LIGHTMAP_OFF
				fixed3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM.xy));
				finalColor.rgb *= lm;
#endif

写法二,TM还是发光

#ifndef LIGHTMAP_ON
				fixed3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM.xy));
				finalColor.rgb *= lm;
				//return fixed4(1, 1, 1, 1);
#endif

写法三,泪流某个海,感觉他应该还是会发光,结果暗了

事实证明,逻辑分析后:

定义与否,你写不写multi_compile ,一点P用没有

这就是很多文章,谬误的地方,问题的重点是,你写不写都没用,然后人家第一句上来就说这个怎么用

你:我想知道怎么用

他:这个这么用,还可以这么写

你:为什么没用

他:你这都不会用,你是不是程序员??可以这么写的

你:但这明明没用啊、、??

他:都说这么用咯。。。。你是不是蠢??

你:。。。。。

所以,作为真正的程序员,更多的时候需要走自己的路,所以搞清楚,并且用好宏定义,是很多程序员晋升的必经之路。

还是回到上面的问题,既然写法三,不发光(生效了)

必然满足2个条件:

1.定义了LIGHTMAP_ON (Unity在某个不知名的地方定义了)

2.某个程序员”大牛“ 这么写,#ifndef LIGHTMAP_ON(是的,字可能太小,这个大牛用了ndef

我被坑了一下午才发现问题,现在知道程序员有多不堪吧,写宏定义害死人,写ndef的更害死人

这时候,如果你没点经验,就会觉得,写成

#ifdef LIGHTMAP_ON

#endif

不是万事无忧咯,这么写的程序员更加不堪。。。。

事实是关于lightmap,关于unityshader宏,这这个例子中,这么一个特例下:

#ifndef LIGHTMAP_OFF
				fixed3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM.xy));
				finalColor.rgb *= lm;
#endif

才是最佳实践

如何理解最佳实践

如果后面有时间会补充说明这个最佳实践

希望大家看完这个文章,能明白

程序员要写好程序,而不是坑人的程序,并不是背2行书,抄点,懂点逻辑,结果就能写出好的程序

基本上好的逻辑都是可以反推的。也就是所谓的逻辑反转

这个例子就是最好的证明

并不是我需要定义宏,然后写ifndef

而是我需要这个Shader由一个灯光开光,被逼要定义宏,

一是没有更好的写法(编程就是这么龌蹉,宏就是那么不堪)

二是这个开光怎么写还是取决于程序员(你自己,做个好人,还是随便做人,其实几率一半一半)

基本上这个Shader代码必须,从下(发光逻辑)写回到上(宏定义)的。。

关于Shader的课题,关于宏定义的课题,关于lightmap太多综合知识了,所以没法在这里详细讲,也可以说,编程已经是一个很综合的学科,而3d编程更加复杂(底层,基础理论很简单),就变的入门门槛很高

不想吐槽那些“知名博主”了

希望大家能对宏定义,由一个概念,并找到解决方法

最后:

(整个文章的Shader我隱藏了一部分代碼,是關於邏輯推理的,真的程序员应该能更好理解这个宏的作用,但又太長太乱,也不是宏定义的关键代码,取舍过后,还是删掉了,干净点)

 完整的宏定义的测试例子这个哥们有:

https://blog.csdn.net/ak47007tiger/article/details/100007655

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

avi9111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值