在编写着色器程序时,我应该避免创建多个变量吗?

11

我现在开始学习着色器(HLSL,GLSL),看了很多教程,发现很少创建变量,这使得阅读变得更加困难。我想知道创建新变量是否会影响着色器的性能。

例如,在CG中:

这个

    inline float alphaForPos(float4 pos, float4 nearVertex){
            return (1.0/_FogMaxRadius)*clamp(_FogRadius - max(length(pos.z - nearVertex.z),length(pos.x - nearVertex.x)), 0.0, _FogRadius)/_FogRadius;
    }

比这更快?
    inline float alphaForPos(float4 pos, float4 nearVertex){
        float distX = length(pos.x - nearVertex.x);
        float distZ = length(pos.z - nearVertex.z);
        float alpha = 0.0;
        alpha = _FogRadius - max(distZ,distX);
        alpha = clamp(alpha, 0.0, _FogRadius);
            return (1.0/_FogMaxRadius)*alpha/_FogRadius;
    }

2
着色器硬件没有调用堆栈,因此像内联和变量作用域这样的概念是非常不同的;然而,在函数声明中设置变量的方式很重要。在GLSL中,您可以在函数声明中使用存储限定符(例如alphaForPos(in vec4 pos,in vec4 nearVertex)),以告诉编译器如果您在函数体内更改了变量的值,则要制作局部副本。另一方面,“inout”意味着允许在函数内部进行的任何更改传播到外部,并且不需要复制。 - Andon M. Coleman
所以在C#中,像是传递引用一样,它不会像在C++中使用const Object &var那样进行复制,对吗? - Hodor
是的,你可以这样想。在像C++这样的语言中,变量的复制并不像不可预测地昂贵,因为它可能会调用一个非平凡的复制构造函数,但你仍然必须处理有限的寄存器空间、浪费的时钟周期等问题。 - Andon M. Coleman
1个回答

11

这不会影响性能。

总的来说,最终所有内容都会被内联化,而编译器的优化部分在完成优化时不会关心单独的变量。

我编译了两个简单的像素着色器,调用了这两个函数,它们都编译成了HLSL中的9条指令。

注重可读性,并相信编译器会做正确的事情(至少在这方面是如此:))。


检查编译后着色器中的指令数量非常有意义。我们相信编译器 :) - Hodor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接