GLSL UBO indexing

Started by CDnoMlqko, October 27, 2020, 17:53:45

Previous topic - Next topic

CDnoMlqko

Hello! I am using LWJGL3 to make a renderer. Let "Materials" be a UBO in a shader, defined this way:

layout(std140, binding=1) uniform Materials {
    Material materials[];
};


and there is the uniform material_index:
uniform int material_index = 0;


In the fragment shader, to determine the material the geometry should be rendered with, I am doing this:
Material mat = materials[material_index];

, which throws an error that is caught with
glGetProgrami(programId, GL_LINK_STATUS)

, but no error log is produced by glGetShaderInfoLog(). The automatic Opengl error callback throws a LOT of errors regarding that the program is not linked correctly when it is used afterwards.

So, modern Opengl (#version 460) should allow array indexes to be uniforms because they are read-only, but it doesn't. Why?

I know there is this workaround:

if(material_index == 0)
    mat = materials[0];
if(material_index == 1)
    mat = materials[1];
...

but it is slow and long and I don't want to use it.

KaiHH

Quote from: CDnoMlqko on October 27, 2020, 17:53:45
...but no error log is produced by glGetShaderInfoLog().
glGetShaderInfoLog() is only to query the logs of shader objects, not of program objects. Linking applies to the program object and would only cause program logs to be generated, which must be queried via: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetProgramInfoLog.xhtml

CDnoMlqko

I added that and this is the error I get:
Fragment info
-------------
0(133) : error C7559: OpenGL requires constant indexes for unsized array access(materials)


Is there any workaround other than making the UBO to have a limited size?

KaiHH

Not with UBOs, however if you are targeting at least OpenGL 4.3, then you can use Shader Storage Buffer Objects, that have much more flexible access rules, such as completely dynamic (not just uniform) indexing.

CDnoMlqko

This looks like a good option. Thank you!