Bug - using varying-like logic(out/in), and sending mat4 from Vertex to Fragment, this mat4 can be ruined if more mat4 logic used in Vertex function.
Bug confirmed - on Linux and Windows on Nvidia 7XX 9XX and 1XXX Series GPU, in OpenGL mode.
The bug does not work in Vulkan and DX11(using ANGLE).
Test:
This bug was found in Godot, and work in any minimal OpenGL3+ engine, this is not Godot bug.
Original Godot bugreport link.
Easy way to test:
- if you on Windows, then disable ANGLE first, launch chrome using
chrome.exe --use-angle=gl
- open this link Web WebGL2 test link
Bug visual result:
Correct visual result:
Shader code of this bug:
Shader code for OpenGL3+, launch in any OpenGL3+ engine.
(this code is right quad on the screenshot, bug result green/white, correct is green/red)
main.vert
#version 300 es
in vec4 position;
out mat4 mtx;
out mat4 tmtx;
void translate(inout mat4 m, vec3 d){
m[3][0] = d.x;
m[3][1] = d.y;
m[3][2] = d.z;
m[3].xyz=d; //does not matter, both does not work
}
void main() {
gl_Position = vec4(position.xyz,1.);
mtx=mat4(vec4(1.),vec4(1.),vec4(1.),vec4(1.));
tmtx=mat4(vec4(0.),vec4(0.),vec4(0.),vec4(0.));
tmtx=mtx;
vec3 a=vec3(1.,0.,0.);
vec3 b=vec3(0.,1.,0.);
//bug
translate(tmtx,a);
//tmtx[3].xyz=a; //fix
mtx[3].xyz=b;
}
main.frag
#version 300 es
#ifdef GL_ES
precision highp float;
#endif
uniform vec2 u_resolution;
out vec4 glFragColor;
in mat4 mtx;
in mat4 tmtx;
void main() {
vec2 uv = gl_FragCoord.xy/u_resolution.xy;
vec3 col = vec3(0.);
if(uv.x<0.5)col = mtx[3].xyz;
else col = tmtx[3].xyz;
glFragColor = vec4(col,1.);
}
For more shaders code look Godot bugreport page, there 5 shaders that display that mat4 completely ruined.
This bug ruin mat4, and this fix in example shader
//bug
translate(tmtx,a);
//tmtx[3].xyz=a; //fix
this fix only this shader because its minimal, this fix does not work in other shaders with more mat4 logic, there everything broke way too much, I did not found a way to fix large shader logic unless moving everything from Vertex to Fragment shader.