unity-shader-ShaderVariant变体及宏及材质编辑器扩展
unity-shader-ShaderVariant变体及宏及材质编辑器扩展
前篇
- 官方文档说明 - https://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html
- unity shader 编辑器扩展类 ShaderGUI - https://blog.csdn.net/WPAPA/article/details/51214368
- 自定义材质面板的小技巧 - https://blog.csdn.net/candycat1992/article/details/51417965#commentsedit ( 有较多的示例 )
- 利用shader_feature打造最小版本Shader - https://zhuanlan.zhihu.com/p/22613359
- UnityShaderVariant的一些探究心得 - https://www.cnblogs.com/Esfog/p/Shader_Variant.html
- 讲述了 shader_feature 中打包 ab 容易踩得坑. ( good )
说明
#pragma shader_feature
和 #pragma multi_compile
相似, 都是起到宏的作用
不同的是 shader_feature 没有用到的不会被包含进去, 而 multi_compile 全部版本都会被包含
所以 shader_feature 材质用, multi_compile 代码控制用.
一般是写 XXX_OFF 或 XXX_ON
另外, 使用 shader_feature 时也极其容器踩坑, 参考 : 踩坑
变体计算
选中 shader, 可以通过减少 #pragma shader_feature
或 #pragma multi_compile
声明的宏, 开查看. 可以看到是成倍的增减
变体的计算, 假设原来初始有 23 个, 加入以下宏申明 ( 假设所有的 shader_feature 都被使用了 )
1 |
总量 = 23 * ( 2 * 3 * 2 ) = 276
使用情况
(非常重要!!!),shader_feature 适用于那些会在材质面板中直接设置的情况,而如果需要在脚本里通过DisableKeyword 和 EnableKeyword 来开启或关闭 keyword 的话就应该使用 multi_compile。(栽过坑啊!!!)并且不要在#pragma后面写注释!!!如果要在脚本里通过 Shader.DisableKeyword 来控制 keyword 的开关的话,不要在 Properties 里写 KeywordEnum,这样可能会导致脚本里的设置失效(可以重新建一个材质解决)。但如果是使用 material.DisableKeyword 来设置的话,就不会有这个问题,原因暂时不明。
材质面板扩展
shader 定义材质面板
- 引用自 : 自定义材质面板的小技巧 - https://blog.csdn.net/candycat1992/article/details/51417965#commentsedit ( 有较多的示例 )
类别 | 描述 |
---|---|
ToggleDrawer | 把一个类型为float的属性显示为一个开关,它的值要么是0要么是1。当选中它时,Unity还会设置一个名为大写属性名_ON(可以自定义名字)的shader feature(需要在shader里使用”#pragma shader_feature”来定义它),我们可以在shader里用过#if、#ifdef或者#if defined关键词来判断它当前是否被开启。 |
EnumDrawer | 把一个类型为float的属性显示为一个下拉列表。可以使用UnityEngine.Rendering命名空间下的各种状态来设置对应的渲染状态,例如ZWrite、ZTest、Blend等。据实验推测,这个值不可以随便定义,老老实实用UnityEngine.Rendering。 |
KeywordEnum | 和EnumDrawer类似,也会把一个类型为float的属性显示为一个下拉列表,但不同的是它会定义一组shader keyword(需要在shader里使用”#pragma multi_compile”来定义它们)。这些keyword的名字是大写属性名_枚举名。同样,我们可以在shader里用过#if、#ifdef或者#if defined配合#elif来判断当前选择是哪个keyword。最多同时支持9个keywords。 |
PowerSliderDrawer | 显示一个非线性响应的滑动条,其中PowerSliderDrawer中的参数指定了底数,然后我们再根据Range()来指定范围。其实简单说来就是滑动条上的数值不再是均匀变化了,而是xsliderxslider进行变化,但我们在shader里还是可以直接访问到一个float数值。 |
1 | Shader "Custom/Material Property Drawer Example" |
cs 脚本扩展材质面板
- unity 内置的 standard shader 机器 cs脚本扩展. builtin_shaders-2018.2.8f1/Editor/StandardShaderGUI.cs
- unity shader 编辑器扩展类 ShaderGUI - https://blog.csdn.net/WPAPA/article/details/51214368
1 | using UnityEngine; |
踩坑
使用shader_feature的shader在bundle中不起作用? - https://answer.uwa4d.com/question/595c9ec472c96d467bd7cfad/
- 使用dummy materials / ShaderVariantCollection 与shader打在同一ab内。
- 使用multi_compile替换shader_feature。