Why are glsl variables not working as expected?

纵然是瞬间 提交于 2020-06-28 06:07:05

问题


I am working on a 3D renderer which was working as expected but now I am trying to batch every cube into a single draw call (my renderer can only draw cubes right now).

Here I have my glsl program that runs for each batch

#type vertex
#version 330 core

layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec4 a_Color;
layout(location = 2) in vec3 a_TexCoord;
layout(location = 3) in int a_TexIndex;

uniform mat4 u_ProjectionView;

out vec4 v_Color;
out vec3 v_TexCoord;
out flat int v_TexIndex;

void main()
{
    v_Color     = a_Color;
    v_TexCoord  = a_TexCoord;
    v_TexIndex  = a_TexIndex;

    gl_Position = u_ProjectionView * vec4(a_Position, 1.0);
}
#type fragment
#version 330 core

out vec4 color;

in vec4 v_Color;
in vec3 v_TexCoord;
in flat int v_TexIndex;

uniform samplerCube u_Textures[32];

void main()
{
    color = texture(u_Textures[v_TexIndex], v_TexCoord) * v_Color;
}

The only part that does not work is the sampling part at the very end.

When I tested my code, I loaded two textures into the u_Textures array in the first two indices and tried to draw a cube with the first texture and another cube with the second texture.

If I hardcode an index like this

color = texture(u_Textures[0], v_TexCoord) * v_Color;

Or like this

color = texture(u_Textures[1], v_TexCoord) * v_Color;

The correct texture at index 0 or 1 is sampled but as soon as I place the v_TexIndex variable, it gives me weird artifacts or just nothing at all.

So I automatically thought that my v_TexIndex variable must not be what I expect it to be but if I replace the line with

color = vec4(v_TexIndex, 1.0, 1.0, 1.0);

I get a white texture when I expect v_TexIndex to be 1 and a turquoise when I expect it to be 0!


回答1:


Arrays of samplers (u_Textures) cannot be indexed by fragment shader inputs such as v_TexIndex.
u_Textures[v_TexIndex] is undefined behavior, because v_TexIndex is not Dynamically uniform.

See GLSL version 4.60 (most recent) (from OpenGL Shading Language 4.60 Specification - 4.1.7. Opaque Types):

When aggregated into arrays within a shader, these types can only be indexed with a dynamically uniform expression, or texture lookup will result in undefined values.

In the GLSL version 330, the restriction is even harder. See OpenGL Shading Language 3.30 Specification - 4.1.7 Samplers:

Samplers aggregated into arrays within a shader (using square brackets [ ]) can only be indexed with integral constant expressions.

That clearly explains why the "hardcode" index (u_Textures[0], u_Textures[1]) works, but u_Textures[v_TexIndex] fails and gives "weird artifacts".

I recommend to use s samplerCubeArray (see Sampler) rather than an array of samplerCube.
When you use a samplerCubeArray, then you don't need any indexing at all, because the "index" is encoded in the 4rd component of the texture coordinate at texture lookup (see texture).




回答2:


I looked at the links that you put in the answer and I did not completely understand how to use samplerCubeArray's; however, I have found a "hack" around my problem and it is by passing the index as a floating point value into the shader program and then texturing like this

color = texture(u_Textures[int(v_TexIndex + 0.5)], v_TexCoord) * v_Color;



来源:https://stackoverflow.com/questions/61873935/why-are-glsl-variables-not-working-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!