Reputation: 157
Let's consider following GLSL examples:
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;
Is 2. faster than 1.? Or are they equal due to obvious compiler optimizations?
What about 3.? Of course this makes no sense, but for the clarity of my shaders code, such redundant texture lookups may occur. I'm wondering if they are optimized / cached somehow or if I should avoid them.
Upvotes: 1
Views: 963
Reputation: 45968
Of course, like others said it depends totally on the implementation. But whereas the compiler may be able to optimize those obvious cases, the situation might be totally different for your actual "real-world" problem.
I was trying to make code more readable and maintainable by reorganization of source, but it could cause some redundant texture lookups. Provided examples were the simplest (and synthetic) possible ways of the problem presentation. They do not present my real solutions.
This sounds like your actual code does not really match the examples you presented, because all three of them are completely ridiculous compared to a simple vec4 val = texture2D(t, coords);
(yes, even the 2nd, like already explained by Sergey) and don't add any readability or maintainability.
So I guess in your actual "real-world" code you seperate out those texturing calls in much more complicated ways, maybe into different functions, or into conditional branches or maybe just separate them by a whole lot of other instructions. And if the compiler can optimize this actual code is a totally different question that needs to be answered for this particular code.
So in the end the only thing you can be certainly sure of is, that example 2 will never be slower than examples 1 and 3. And on the other hand that the optimization behaviour for your 3 examples doesn't tell you anything practically, because that is surely not your actual "real-world" code, which might be arbitrarily more complex to analyse by the optimizer. (And if it is indeed your "real-world" code, then your definition of "real" doesn't really match the real definition of "real" and Sergey's answer is the only correct one).
Upvotes: 1
Reputation: 25396
It is not mentioned in the spec that the GLSL compiler should do any optimizations. This means the better way is to avoid premature pessimization. This code
uniform sampler2D t;
void main() {
vec4 val = texture2D(t, coords);
is the best one. No reason to create float variables, because you always can access vector's components directly via val.x
etc.
Upvotes: 3