更改相机着色器属性

问题描述 投票:0回答:2

我需要设置一个着色器的变量,但没有包围它的材质。

我将解释这个问题以及为什么它不像问题“如何从脚本访问着色器变量?”。

问题

我的着色器与此类似(删除了 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 的概念甚至不适用于默认着色器。

我在网上和文档中搜索了几个小时。我承认我失败了,我在这里不知所措。我想这一定很简单,但我找不到任何文档。

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

c# unity-game-engine shader
2个回答
2
投票

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

确实如此,但材质只是公开着色器的所有属性,因此它与此处相关,因为您想要更改着色器属性。

您有一个自定义着色器,但它不用于渲染游戏对象,而是用于渲染相机。 仍然需要材质来更改着色器。如果您不想使用材质,那么您可以使用

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")


0
投票

我无法从程序员那里得到上述答案来工作。这里使用 Unity 2022.3 URP 是另一种解决方案:

  1. 通过脚本 (CameraEffect.cs) 将自定义材质添加到相机,并将着色器设置为该材质,请参阅下面的代码(此步骤的教程在此处:https://www.youtube.com/watch?v= HW8UePVtU5M).

  2. 在着色器中,公开需要设置为属性的变量——该属性随后将出现在自定义材质的检查器中。

  3. 在CameraEffect.cs中公开一个公共变量并对材质执行SetFloat/Color/等操作(如下代码)。

  4. 在单独的游戏对象控制器脚本中创建一个 CameraEffect 类型的公共变量(即“publiccameraEffect camShaderControl;”),它将出现游戏对象的检查器。然后在编辑器中将主摄像机拖到检查器中的 camShaderControl 框中。然后可以通过 camShaderControl.myValue 在外部脚本中访问 myValue

此解决方案可能因新版本 Unity 中的后处理量而过时,但据我所知,整个问题仍然很模糊。

    public class CameraEffect : MonoBehaviour
    {
    public Material material;
    public float myValue = 0.0f;

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (material == null)
        {
            Graphics.Blit(source, destination);
            return;
        }
        Graphics.Blit(source, destination, material);
        material.SetFloat("_camPos", myValue);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.