Notifications
Article
通过脚本访问或修改Shader参数
Published 18 days ago
16
0
在Inspector面板看到的Shader所有参数都可以通过脚本访问或修改,并动态改变纹理。例如修改材质的颜色、为材质分配一个新的纹理等。本篇文章以Standard为例进行讲解)。
我们知道,Standard和Standard(Specular setup)着色器是基于PBR中的金属和镜面工作流。
Standard实际上并不是单个的着色器,而是许多不同着色器的组合,这些不同类型的着色器叫做着色器的变体。例如,如果你分配了一张法线贴图到材质中,你就激活了支持法线贴图的着色器变体。如果你又分配了一张高度图,你就激活了同时支持法线贴图和高度图的着色器变体。
这是一个很好的设计,因为这意味着如果你使用了Standard着色器,但是没有使用法线贴图,那么就不会有运行法线贴图的着色器代码带来的性能开销。因为如果你从未使用某个属性(例如法线贴图、高度图等),那么该变体将完全从你的项目发布中省略。
Unity不会在你的项目发布中包含所有的着色器变体,因为这是一个数以千计的数量。取而代之的是,Unity通过检测你的项目中使用的材质资源,追踪你使用过的变体,你在项目中使用的标准着色器中包含了哪些变体,在项目发布时就会包含它们。

1.如果你使用脚本改变了着色器中某个属性,就必须使用EnableKeyword方法开启该变体

GetComponent<MeshRenderer>().material.EnableKeyword("_NORMALMAP"); GetComponent<MeshRenderer>().material.SetTexture("_BumpMap", myNormalMap);
开启Standard着色器变体所需的特殊关键字:
_NORMALMAP:Normal Mapping(法线贴图) _ALPHATEST_ON:Cut out(剔除)渲染模式 _ALPHABLEND_ON:Fade(淡入淡出)渲染模式 _ALPHAPREMULTIPLY_ON:Transparent(透明)模式 _EMISSION:Emission(自发光)颜色或贴图 _PARALLAXMAP:Height Mapping(高度图) _DETAIL_MULX2:Secondary Maps(次要细节贴图)反照率&法线贴图 _METALLICGLOSSMAP:金属工作流中的Metallic/Smoothness(金属/平滑度贴图) SPECGLOSSMAP:镜面工作流中的Specular/Smoothness(镜面/平滑度贴图)
然而遗憾的是,Unity只检测你项目中使用的材质,以决定哪些变体将被包含在项目发布中,而不会包含那些只在运行时通过脚本调用的变体。这意味着,如果你在脚本中为材质开启了_NORMALMAP关键字,但是项目中没有一个材质使用了法线贴图属性,那么法线贴图将不会在你项目发布后起作用(即使在编辑器中能正常工作)。这是因为法线贴图变体“看起来”没有被使用(虽然代码激活,但是编辑器中并未赋值,会被Unity认为该变体未使用),所以该变体从项目发布中被省略了!

2.你必须确保项目发布时包含你所需的着色器变体

即便你满足了第1条(使用关键字开启了着色器某个属性),但如果你的项目中没有其他任何对象的材质属性面板中指定了该属性,你的项目发布后,你试图通过代码改变该属性仍将不起作用。所以你的场景中必须至少有一个对象属性面板赋值了该属性,或者被放置在Resources文件夹中,否则Unity将从项目发布时剔除它,因为它看起来没有被使用。
综上所述,你使用代码改变着色器属性要满足一下条件:
  1. 开启变体对应的关键字并赋值;
  2. 场景中至少有一个对象的Inspector属性面板Standard着色器使用了该变体或Resources文件夹中有Standard着色器
完成上述两个步骤,你现在已经完全可以在运行时改变使用了Standard着色器的材质。
Tags:
尹煜
北京宏宇航天技术有限公司Unity工程师 - Programmer
28
Comments