更改相机着色器属性

时间:2018-10-21 14:58:10

标签: c# unity3d shader

我需要设置一个着色器的变量,而没有环绕它的材质。

我将解释问题以及为什么它不像问题“ How can I access shader variables from script?”那样。

问题

我的着色器与此类似(删除了不相关的样板代码的99%):

Shader "Hidden/XShader"
{
    Properties
    {
        _x ("", float) = 0
    }

    SubShader
    {
        Pass
        {
            float _x;

            half4 frag(v2f i) : SV_Target
            {
                // "col" and "wpos" have been correctly defined

                if (wpos.x >= _x)
                {
                    col.r = 1;
                } else {
                    col.r = 0;
                }

                return col;
            }
        }
    }
}

此着色器是通过Edit->Project Settings->Graphics->Deferred选项设置的。这是主相机使用的默认着色器。

现在,我需要根据摄像机附带的代码设置_x值:

public class XCameraController : MonoBehaviour
{
    public float x;

    void Update()
    {
        <something>.SetFloat("_x", x);
    }
}

<something>占位符通常是材料,因为在那里定义了SetFloat()。但是相机和着色器没有材质。 material 的概念甚至不适用于默认着色器。

我已经在线搜索了数小时。我承认我失败了,在这里茫然。我想这一定很简单,但是我找不到任何文档。

我不希望有一个已实现的解决方案,一个可以找到帮助的指针就足够了!

1 个答案:

答案 0 :(得分:1)

  

但是相机和着色器没有材质。概念   材质甚至不适用于默认着色器。

是的,但是材料只是公开了着色器的所有属性,因此在这里很重要,因为您要更改着色器的属性。

您有一个自定义着色器,但这不是用来渲染GameObject而是用来渲染摄影机的。 仍然需要一种材质来更改着色器。如果您不想使用材质,则可以使用Shader.SetGlobalXXX之类的Shader.SetGlobalFloat("_x", 3)函数,但它将更改所有内容。着色器属性。这是不现实的。


执行此操作的正确方法是创建一个临时材质,以用于修改材质球,更改材质球属性,然后更新相机正在使用的材质球。为此,您必须:

找到着色器或使用公共变量获取着色器的引用:

Shader camShader = Shader.Find("Hidden/XShader");

从着色器创建材质

Material camMat = new Material(camShader);

根据需要修改属性

camMat.SetFloat("_x", 3);

将修改后的着色器属性应用于相机

Camera.main.SetReplacementShader(camShader, "RenderType");

如果您要手动渲染相机,请使用Camera.main.RenderWithShader(camShader, "RenderType")代替Camera.main.SetReplacementShader(camShader, "RenderType")