Im trying to implement a batch renderer. But when i try to index an array of
sampler2D using non constant value, it doesnt work - everything is black. However when i use a constant value - it works.
Here is the code:
This one does NOT work
vec4 pixel = vec4(1.0);
int slot = 0;
pixel = texture(u_tex[slot], v_uv);
This one IS working
vec4 pixel = vec4(1.0);
pixel = texture(u_tex, v_uv);
Prior to GLSL 4.0, arrays of samplers can only be indexed with constant expressions. In 4.0 or later they can be indexed with dynamically-uniform expressions (expressions whose value is the same for all invocations within a workgroup). This includes expressions which depend only upon uniform variables, but anything beyond that is implementation-defined. It typically includes per-draw (in the sense of
glMultiDraw*) data and per-instance data in the vertex shader and per-primitive data (e.g.
flat-qualified inputs) in the fragment shader, but even that isn’t guaranteed.
If all of the textures have the same format, dimensions, and sampling parameters (
glTexParameter*), consider using an array texture rather than distinct textures. There are no restrictions on the expression used to determine the layer of an array texture (it can vary per-vertex or per-fragment).
Look at both 1) 2D array textures and 2) Bindless textures to see which best fits your needs:
Both can allow you to batch draw calls together that refer to separate 2D textures.
With 2D array textures, you need to pre-bake all the individual 2D textures into a single 2D array texture. In the shader, the 3rd component of the texcoord you pass to
texture() selects the 2D array texture slice/layer.
With bindless texture, you do not need to pre-bake the 2D textures all together. You simply make the individual 2D textures GPU resident, pass the 64-bit bindless handles for each into the shader in uvec2’s, and then just cast these to sampler2D() in the shader when calling
texture() (or other texture functions). For example:
flat in uvec2 texHandle; // Bindless texture handle
vec4 val = texture( sampler2D( texHandle ), texcoord );
Note that bindless texture does not work unless the texture you access with it is dynamically uniform (or you’re on NVidia hardware). By contrast, you can use an arbitrary index for array textures.
@BANEBYTE, here’s more on that “Dynamically uniform” term, in case it’s new to you:
Example: If all fragment shaders for a single primitive lookup into the same texture using the same handle, you should be fine.
This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.