在unity中我们可以通过使用#pragma multi_compile或#pragma shader_feature指令来为shader创建多个稍微有点区别的shader变体。这个Shader被称为宏着色器(mega shader)或者超着色器(uber shader)。实现原理:根据不同的情况,使用不同的预处理器指令,来多次编译Shader代码。 在运行时,Unity从Material宏Material.EnableKeyword和...
我们用ShaderLab编写Unity中的Shader,当我们需要让Shader同时满足多个需求,例如,这个是否支持阴影,此时就需要加Keyword(关键字),例如在代码中#pragma multi_compile SHADOW_ON SHADOW_OFF,对逻辑上有差异的地方用#ifdef SHADOW_ON或#if defined(SHADOW_ON)区分,#if defined()的好处是可以有多个条件,用与、或逻辑运算...
我们用ShaderLab编写Unity中的Shader,当我们需要让Shader同时满足多个需求,例如说,这个是否支持阴影,此时就需要加keyword(关键字),例如在代码中#pragmamulti_compileSHADOW_ON SHADOW_OFF,对逻辑上有差异的地方用#ifdef SHADOW_ON或#if defined(SHADOW_ON)区分(#if defined()的好处是可以有多个条件,用与、或逻辑运算...
第一个是在shader_feature后面只跟了一个宏的时候,会生成两个变体,一个是不包含该宏,另一个是包含该宏。另一个区别是打包时的表现。在打包的时候shader_feature不会包含没有使用的变体,而multi_compile会排列组合所有变体。 2.变体 Unity在编译shader时,不同的宏组合会生成独立的shader程序,这些独立的shader程序...
1.1 multi_compile和shader_feature的区别 用multi_compile声明的Keyword是全排列组合,例如: #pragma multi_compile A B #pragma multi_compile C D E 组合出来就是AC、AD、AE、BC、BD和BE6个,如果再来一个#pragma multi_compile F G显然会直接翻倍为12个。
一、什么是Shader变体管理 想要回答这个问题,要看看什么是Shader变体。 1. 变体 我们用ShaderLab编写Unity中的Shader,当我们需要让Shader同时满足多个需求,例如说,这个是否支持阴影,此时就需要加keyword(关键字),例如在代码中#pragma multi_compile SHADOW_ON SHADOW_OFF,对逻辑上有差异的地方用#ifdef SHADOW_ON或#if...
打包时会将multi_compile和shader_feature分为两堆,分别计算组合数,然后两者再组合,例如: 当你只打两个材质,引用的变体分别是ADEG和ACFH,前两个multi_compile组直接组合成4个变体,后面两个shaderfeature组分别引用到了EG和FH,然后两组组合4*2,最后打出8个变体。
shader_feature_local的_local声明和变体数无关,是Unity2021之前为了解决GlobalKeyword数量问题出现的解决方案,声明为local keyword不会占用global keyword数,建议是如果keyword声明组是需要材质手动勾选的参数,声明为_local;当keyword为local时,Shader.EnableKeyword或CommandBuffer.EnableKeyword这种全局开启keyword方式,...
使用本地宏替代一部分全局宏:使用shader_feature_local和multi_compile_local。 shader_feature_local:类似于shader_feature,但枚举宏是本地的。 multi_compile_local:类似于multi_compile,但枚举宏是本地的。 在项目中除非是希望通过全局API启用的那些特定宏,否则应尽量使用本地宏, ...
shader_feature_local:类似于shader_feature,但每个关键字都是局部的。 multi_compile_local:类似于multi_compile,但每个关键字都是局部的。 局部指令将保留定义的关键字都在定义它们的shader里,而不是引用于整个项目的。就为了这个原因,你就应该使用局部的关键字来替代全局关键字,除非你需要通常全局的脚本API来控制指...