In my nVidia with OpenGL 4.3, second approach works fine, but first approach fails with:
error C5208: Sampler needs to be a uniform (global or parameter to main), need to inline function or resolve conditional expression
is this a bug, or something else?
uniform sampler2DArray texRGB;
uniform sampler2DArray texRGBA;
vec4 color = texture(isRGBA ? texRGBA : texRGB, coords);
if (isRGBA) color = texture(texRGBA, coords);
else color = texture(texRGB, coords);
A variable of sampler type can only be used, as part of an expression, as an argument to a function (you can use
.length() on arrays of samplers). The
?: operator is not an argument to a function, so a sampler type cannot be used that way.
Also, be aware of the problems of using conditional logic with texture fetching. So long as
inRGBA is potentially non-uniform, then you won’t get proper derivatives.
vec4 color = isRGBA ? texture(texRGBA, coords) : texture(texRGB, coords);
But this has the same issue with the use of implicit derivatives in non-uniform control flow.
That can be avoided with:
vec4 color1 = texture(texRGBA, coords);
vec4 color2 = texture(texRGB, coords)
vec4 color = isRGBA ? color1 : color2;
or (probably more efficiently) with:
vec2 dx = dFdx(coords);
vec2 dy = dFdy(coords);
vec4 color = isRGBA ? textureGrad(texRGBA, coords, dx, dy) : texture(texRGB, coords, dx, dy);
As a Red Book reader and beginner, I totally miss the need for this partial derivative thing.
Very helpful and interesting.
Thank you guys!
PS: I totally doesn’t understand why on non-uniform flow, hardware cannot apply finite differences on neighbor fragments. (I ask just for curiosity).
I totally doesn’t understand why on non-uniform flow, hardware cannot apply finite differences on neighbor fragments.
Because finite differences only work if the neighboring fragments are computing using the same sequence of operations. Once you’re in non-uniform control flow, there is no guarantee that neighboring fragments are doing anything even remotely like one another.