I’ve had a bit of a nightmare getting SPIRV shaders running on OpenGL 4.6
That’s probably a story for a different thread.
For now, I’ve progressed to a point where (on Intel at least) my shaders all appear to be executing and rendering correctly.
There is one aspect that I don’t understand, that I’m hoping someone can help illuminate (I’m not well versed in GLSL, this may be obvious to others).
At first, one of my shaders was failing because I had two seperate sampler objects defined at different locations, like so:
layout(binding = 0) uniform sampler2D DiffuseSampler;
layout(binding = 1) uniform sampler2D NormalMapSampler;
It turns out, this isn’t supported. Something about seperable samplers not being supported in SPIRV.
Does that mean I can’t have multiple sampler objects targeting different texture units?
There seem to be only two combinations that result in an operational shader:
A) I could not specify a location at all. As I understand it, the SPIRV compilation process will emit these samplers to the same binding:
uniform sampler2D DiffuseSampler;
uniform sampler2D NormalMapSampler;
B) Explicitly define these samplers to the same binding:
layout(binding = 0) uniform sampler2D DiffuseSampler;
layout(binding = 0) uniform sampler2D NormalMapSampler;
Either approach should boil down to the same thing as I understand it.
A few initial questions…
- Does binding in this case refer to the texture unit, or something else entirely?
- Does it follow, that I can only bind to a single texture unit in any given shader?
Rewinding back to the traditional method of loading/compiling/binding shaders at runtime, I could use introspection to determine the location of those sampler uniforms, and then bind them to specific texture units via glUniformiv
That all made sense, I just bind the diffuse texture to GL_TEXTURE0
and the normal map texture to GL_TEXTURE1
, tell the sampler objects which one is which (or just hardcode it) and we’re good.
It seems like this isn’t possible with SPIRV shaders.
So, how exactly do I indicate to the sampler2D objects which texture units to sample from?
I think the answer is to use GL_TEXTURE_2D_ARRAY
and then I can explicitly reference each layer in shader code - but, is this the correct use case? Is there some other way to do it or have I got things entirely backward?
I would greatly appreciate input from wiser folk.