如何在ShaderLab中缓存通用(对于所有像素)变量?

时间:2019-05-25 10:09:32

标签: unity3d shader fragment-shader shaderlab

假设我具有以下着色器:

Shader "Sprites/X"
{
    Properties
    {
        [HideInInspector] _MainTex("Sprite Texture", 2D) = "black" {}
    }

    SubShader
    {
        Pass
        {
            CGPROGRAM

            // bla bla

            fixed4 frag(v2f i) : SV_Target
            {
                float a = calculateA();
                float b = calculateB();
                .
                .
                .
                float z = calculateZ();

                // Here the values above mix with x-y position of the pixel
                // and then return a color
            }
            ENDCG
        }
    }
}

在上面的代码中,我需要从相关函数a-z中计算变量calculateA()-calculateZ()的值(这只是一个概括示例)。假设这些功能很复杂,并且它们依赖于在每一帧中更改的着色器的其他属性,而不是像素本身。我们知道,每次为每个像素计算复杂函数。

有一种方法可以“缓存”这些值,以避免每次为每个像素进行计算?在每一帧中,所有像素的值都相同。

当前,我通过使用以下方法在C#脚本中设置值来解决此问题:

gameObject.GetComponent<Renderer>().material.SetFloat("a", calculateA());
.
.
.
gameObject.GetComponent<Renderer>().material.SetFloat("z", calculateZ());

但是我更喜欢保留着色器和C#脚本代码分开。

1 个答案:

答案 0 :(得分:0)

好吧,这就是您要做的:)

这取决于您为什么要避免使用C#

  • 如果仅从常量中计算出所述方法,则编译器 可以优化它。
  • 如果该方法的可预测结果很少 您可以将它们预先计算为着色器本身声明的数组,也可以从代码(而不是每个帧)设置一次。
  • 如果有很多可预测的结果,您可以考虑烘烤它们 进入纹理,或者如果可以使用现代GPU,则进入结构化 缓冲区。