GLSL - 是否优化了纹理查找?

时间:2012-07-25 10:32:28

标签: optimization opengl glsl shader textures

让我们考虑以下GLSL示例:

1

uniform sampler2D t;
...
void main() {
   float val_r = texture2D(t, coords).r;
   float val_g = texture2D(t, coords).g;
   float val_b = texture2D(t, coords).b;
   float val_a = texture2D(t, coords).a; 

2

uniform sampler2D t;
...
void main() {
   vec4 data = texture2D(t, coords);
   float val_r = data.r;
   float val_g = data.g;
   float val_b = data.b;
   float val_a = data.a; 

3

uniform sampler2D t;
...
void main() {
   vec4 data1 = texture2D(t, coords);
   vec4 data2 = texture2D(t, coords);
   vec4 data3 = texture2D(t, coords);
   vec4 data4 = texture2D(t, coords);
   float val_r = data1.r;
   float val_g = data2.g;
   float val_b = data3.b;
   float val_a = data4.a; 

2.比2快吗? 或者由于明显的编译器优化它们是否相同?

3怎么样?当然这没有意义,但为了清晰我的着色器代码,可能会发生这种冗余纹理查找。我想知道它们是否以某种方式进行了优化/缓存,或者是否应该避免使用它们。

2 个答案:

答案 0 :(得分:4)

规范中没有提到GLSL编译器应该进行任何优化。这意味着更好的方法是避免过早的悲观情绪。这段代码

uniform sampler2D t;

void main() {
   vec4 val = texture2D(t, coords);

是最好的。没有理由创建浮点变量,因为您始终可以通过val.x等直接访问矢量组件。

答案 1 :(得分:1)

当然,和其他人一样,它完全取决于实施。但是,虽然编译器可能能够优化那些明显的情况,但实际的“真实世界”问题的情况可能完全不同。

  

我试图让代码更具可读性和可维护性   重组源,但它可能会导致一些冗余的纹理   查找。提供的示例是最简单的(和合成的)可能的   问题表达的方式。他们没有表达我的真实   的解决方案。

这听起来像你的实际代码与你提供的例子并不完全匹配,因为与简单的vec4 val = texture2D(t, coords);相比,它们中的三个都是完全荒谬的(是的,即使是第二个,就像已经由 Sergey解释的那样)并且不添加任何可读性或可维护性。

所以我想你的实际的“真实世界”代码你可以用更复杂的方式分离那些纹理调用,可能分成不同的函数,或者分成条件分支,或者只是将它们分开来很多其他指示。如果编译器可以优化这个实际代码是一个完全不同的问题,需要回答这个特定的代码。

所以最后你唯一可以确定的是,示例2永远不会比示例1和3慢。而另一方面,你的3个例子的优化行为并没有告诉你什么实际上,因为那肯定不是你真正的“真实世界”代码,优化器分析这些代码可能会更加复杂。 (如果它确实是您的“真实世界”代码,那么“real”的定义 > “真实”的真实定义谢尔盖的答案是唯一正确的答案。)