opengl - Strange behavior of GLSL array-element-operator on sampler2D array -


i'm writing simple shader , ran strange problem.

i'm rendering bunch of textures using sampler2d array select texture needed.

#version 330 core  layout (location = 0) out vec4 color;  in data {     vec4 position;     vec4 color;     vec2 texcoord;     flat int texid; } fs_in;  uniform sampler2d textures[16];  void main() {     vec4 texcolor = fs_in.color;     if (fs_in.texid > 0)     {         texcolor = fs_in.color * texture(textures[fs_in.texid - 1], fs_in.texcoord);     }     color = texcolor; } 

this code, however, gives me strange artifacts on textures: image

now here strange part:

replacing

texcolor = fs_in.color * texture(textures[fs_in.texid - 1], fs_in.texcoord); 

with following

for (int = 0; < 16; i++)     if (fs_in.texid - 1 == i)         texcolor = fs_in.color * texture(textures[i], fs_in.texcoord); 

fixed problem: image

also, problem appearing on amd based computer using opengl 4.5.13469 compatibility profile context 21.19.525.258

running original program on surface pro works fine.

maybe i'm missing obvious, have no clue why problem occurring or why change fixed it. explanation appreciated.

~ stone

#version 330 core 

in glsl 3.30, arrays of samplers can only accessed constant expressions. shader should not have compiled.

but let's pretend hardware supports more glsl 3.30. in case:

textures[fs_in.texid - 1] 

in glsl 4.00+, arrays of samplers can only accessed dynamically uniform expressions. , unless you're rendering 1 triangle, or every triangle has same fs_in.texid value, expression not dynamically uniform. , i'm guessing it's not, since didn't use uniform.

if index array of opaque types expression not dynamically uniform, undefined behavior.

with following

for (int = 0; < 16; i++)     if (fs_in.texid - 1 == i)         texcolor = fs_in.color * texture(textures[i], fs_in.texcoord); 

even invokes undefined behavior. while expression i may dynamically uniform, because statement executed conditionally, condition not guarantee value of i used same invocations within invocation group.

so it's still not dynamically uniform. it's undefined behavior happened work. there's no guarantee work on else.

you can't escape rules; cannot switch texture use in middle of rendering command. if that's want, don't want array of textures; want array texture:

uniform sampler2darray textures;  void main() {     vec4 texcolor = fs_in.color;     if (fs_in.texid > 0)     {         texcolor = fs_in.color * texture(textures, vec3(fs_in.texcoord, fs_in.texid - 1));     }     color = texcolor; } 

or, remove condition, make layer 0 of texture contain ones, , fetch texture (since doing conditionally may require manually provide derivatives):

uniform sampler2darray textures;  void main() {     color = fs_in.color * texture(textures, vec3(fs_in.texcoord, fs_in.texid)); } 

Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -