如何实时在着色器之间切换?

时间:2018-02-01 09:39:27

标签: unity3d unity5 unityscript

问题是我有两个着色器。如果我在游戏运行时在着色器之间切换它将不会生效。只有当我使用当前着色器启动游戏时,它才会使用着色器,但不会使用我切换到的着色器。

我看到了这段代码,但它是切换材料,我想切换着色器。 我的意思是在同一个GameObject上的着色器之间切换。我不确定此代码中应包含哪些材料?

var materials : Material[];
var count = 0;

function OnMouseDown() {
    if (count == materials.Length - 1)
        count = 0;
    else
        count++;

    renderer.material = materials[count];
}

2 个答案:

答案 0 :(得分:1)

您可以使用GameObject.renderer.material.shader设置着色器。 API就是这个东西的例子。查看documentation

答案 1 :(得分:1)

简答

不要这样做。通过游戏对象的渲染器分配更改material的{​​{1}}属性会导致创建多个材质实例,这不仅在计算上很昂贵,而且在GPU上的内存方面也很昂贵。

Thomas of Unity Tutorials说得最好:

  

最有可能进入你脑海的第一件事是:

     

shader

     

简单,对吗?抓住那种颜色并制作动画。这样做的问题是,为了改变着色器中的颜色,Unity需要告诉GPU该对象将以不同方式呈现,并且它可以这样做的唯一方法是更改​​材质实例。因此,当您第一次访问renderer.material时, Unity会创建材料的副本

     

这意味着有很多很多的素材副本,所有吃内存 1

2500个球体的场景共享相同的材料。其他39种材料用于场景中的其他项目。 1

enter image description here 1

在2500个物体上摆弄GetComponent<Renderer>().material.color = ...之后。请注意材料跳跃 40到2540 材料!

enter image description here 1

长答案

首先是复习。在Unity中,您可以创建(或从资源商店购买)着色器,然后创建材质。然后,材质引用着色器,提供着色器可能需要的任何参数,例如纹理;凹凸贴图;和标量可以将此材料与可能使用相同着色器的任何其他材质区分开来。完成后,将材质应用于对象。

  

我的意思是在同一个GameObject上的着色器之间切换

因此想要切换着色器并没有多大意义。对象直接与着色器对话不仅不正确,而且着色器也没有足够的细节来执行此操作。

您想要做的是切换材料对象而不是

  

如果我在游戏运行时在着色器之间切换它将不会生效

没有看到你的代码,很难说。无论如何,你最好提前定义所有资产而不是动态创建。通过这种方式,您可以将其烘焙为已知的保真度或平台,而代码不必决定应该使用哪个着色器级别。

变通

如果您必须在运行时更改材料,则可能需要考虑Unity的GameObject.renderer.material.shader

  

Graphics.DrawMesh和Renderer.SetPropertyBlock使用MaterialPropertyBlock。在要使用相同材质绘制多个对象但属性略有不同的情况下使用它。例如,如果要稍微更改绘制的每个网格的颜色。不支持更改渲染状态More...

很遗憾,虽然您现在需要将MaterialPropertyBlock添加到着色器中,正如Thomas在下面的文章中所解释的那样。

这么简单的事情有很多复杂性。提前预先设计的材料要好得多。这可以说是一种更好的做法。

告诉我更多

  1. 优秀文章 THE MAGIC OF MATERIAL PROPERTY BLOCKS

  2. "Change the color of a material for only one object" Answers, Unity