美文网首页征服Unity3d何三思Unity技术分享
【Unity3D技术文档翻译】第2.5篇 通过脚本访问和修改材质

【Unity3D技术文档翻译】第2.5篇 通过脚本访问和修改材质

作者: 何三思 | 来源:发表于2018-06-28 10:05 被阅读29次
    Unity3D技术文档翻译

    上一章:【Unity3D技术文档翻译】第2.4篇 PBR材质验证器(Physically Based Rendering Material Validator)

    本章原文所在章节:【Unity Manual】→【Graphics】→【Graphics Overview】→【Materials, Shaders & Textures】→【Standard Shader】→【Accessing and Modifying Material parameters via script】

    通过脚本访问和修改材质参数

    当查看一个材质时,所有你能看到的参数都可以通过脚本获取,赋予你在运行时改变参数的能力。

    这允许你在材质上更改数字值、颜色,以及在游戏中动态替换纹理。一些最常用的方法如下所示:

    方法名 使用
    SetColor 改变材质的颜色(比如反照率色调颜色)eg: GetComponent<Render>().material.SetColor("_Color", Color.green);
    SetFloat 设置一个浮点值(比如法线贴图乘数因子)eg: GetComponent<Render>().material.SetFloat("_Shininess", shininess);
    SetInt 设置材质的整数值
    SetTexture 为材质分配一个新的纹理 eg: GetComponent<Render>().material.SetTexture ("_MetallicGlossMap", m_MetalTexture);

    通过脚本操作材质的完整方法集可以在 Material class scripting reference(材质类脚本参考) 中找到。

    一个重要的注意事项是,这些方法只能设置可从当前着色器中获得的属性。这意味着,如果你有一个没使用任何纹理的着色器,或者你没有绑定任何着色器,那么调用 SetTexture 方法将没有任何效果。就算你后来为着色器设置了所需的纹理也是如此。因此,建议你在设置任何属性前,先设置着色器。一旦你设置好着色器,依旧可以从一个着色器切换到另一个,同时纹理和属性值将会被保留。

    这些方法只在所有简单的着色器中有效,比如遗留的着色器,以及内置的除了标准着色器(Standard Shader)之外的着色器(比如:particle、sprite、UI、unlit shaders)。对于只用了标准着色器的材质,在你改变材质之前,你必须意识到有一些更深层次的需求。

    标准着色器脚本的特殊需求

    如果你想要在运行时改变材质,标准着色器有些额外的需求,因为——在场景幕后——它实际上是许多不同的着色器合为一体。

    这些不同类型的着色器叫做着色器变体(Shader Variants),可以被当做着色器属性在激活或者不激活时的所有可能组合。

    举个例子,如果你分配了一张法线贴图到材质中,你就激活了支持法线贴图的着色器变体。如果你后来又分配了一张高度图,你就激活了同时支持法线贴图和高度图的着色器变体。

    这是一个很好的系统,因为这意味着如果你使用了标准着色器,但是没有使用法线贴图,那么就不会有运行法线贴图着色器代码带来的性能消耗——因为你正在运行的是一个不包含法线贴图着色器代码的变体。这也意味着,如果你从未使用某个特性组合(比如高度图与自发光贴图的组合),那么该变体将完全从你的构建中省略——实际上,你将只使用一个非常小数量的可能用到的标准着色器变体。

    Unity 避免在构建中简单地包含每一个可能用到的着色器变体,因为这将是一个非常大的数目,数以千计!如此高数量的结果就是,不仅仅是材质检查器中可能用到的特性组合,那些在不同渲染情景下的每个可能组合也会存在,比如:是否使用了 HDR、光照贴图、全局光照、烟雾等等。包含所有这些将导致加载缓慢、高内存占用,并增加构建大小和时间。

    取而代之的,Unity 通过检测你项目中使用的材质资源,追踪你使用过得变体。你在项目中的标准着色器中包含了哪些变体,在构建时就会包含它们。

    当想要从标准着色器中获取材质时,有两个单独的问题需要注意。

    1. 你必须为所需的标准着色器变体开启正确的关键字

    如果你使用脚本改变了材质,导致它使用了标准着色器的不同变体,你就必须使用 EnableKeyword 函数开启那个变体。如果你使用了一个在一开始没有初始化的着色器特性,一个不同的着色器变体将被需要。举个例子,为一个没有法线贴图的材质分配一张法线贴图,或者设置自发光等级的值大于0。

    下表中展示了开启标准着色器变体所需的特殊关键字:

    关键字 特性
    _NORMALMAP Normal Mapping(法线贴图)
    _ALPHATEST_ON “Cut out” Transparency(剔除)渲染模式
    _ALPHABLEND_ON “Fade” Transparency(渐变)渲染模式
    _ALPHAPREMULTIPLY_ON “Transparent” Transparency(透明)模式
    _EMISSION Emission Colour(自发光颜色)Emission Mapping(自发光贴图)
    _PARALLAXMAP Height Mapping(高度图)
    _DETAIL_MULX2 Secondary “Detail” Maps(二级细节贴图) (反照率 & 法线贴图)
    _METALLICGLOSSMAP 金属工作流中的 Metallic/Smoothness Mapping(金属/平滑度贴图)
    _SPECGLOSSMAP 镜面工作流中的 Specular/Smoothness Mapping(镜面/平滑度贴图)

    当在编辑器中运行时,上述关键字足够使用脚本改变材质。

    然而,因为 Unity 只检测你项目中使用的材质,以决定哪些变体将被包含在构建中,而不会包含那些只在运行时通过脚本调用的变体。

    这意味着,如果你在脚本中为材质开启了 _PARALLAXMAP 关键字,但是项目中没有一个材质使用了相同特性组合,那么视差贴图将不会在最终构建中起作用——即使它在编辑器中能正常工作。这是因为它看起来没有被使用,所以从构建中被省略了。

    2. 你必须确保 Unity 包含了你构建中所需的着色器变体。

    为了实现这点,你的资源中至少要有一个材质包含了你想要使用的着色器变体,以确保 Unity 知道它。该材质必须在场景中被使用,或者被放置在Resources 文件夹中——否则 Unity 将从构建中剔除它,因为它看起来没有被使用。

    通过完成上述两个步骤,你现在已经完全可以在运行时改变使用了标准着色器的材质。

    如果你对学习更多关于着色器变体的细节,以及如何写自己的着色器感兴趣,请看 Making multiple shader program variants here 一节。

    如果本文对你有帮助的话,点个赞或者评论一下吧!

    下一章:【Unity3D技术文档翻译】第2.6篇 编写着色器 (材质、着色器与纹理系列完结)

    相关文章

      网友评论

        本文标题:【Unity3D技术文档翻译】第2.5篇 通过脚本访问和修改材质

        本文链接:https://www.haomeiwen.com/subject/jwwiyftx.html