Skip to content

Instantly share code, notes, and snippets.

@code-disaster
Last active February 10, 2016 12:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save code-disaster/fb0a0126f40556da4b82 to your computer and use it in GitHub Desktop.
Save code-disaster/fb0a0126f40556da4b82 to your computer and use it in GitHub Desktop.
Shader bug(?) on Windows w/Intel GPU

This is a custom shader we are using right now to render flat shaded geometry into a deferred render buffer. Please ignore the custom made stuff (#pragma), it shouldn't be of relevance in this case.

Now, this shader works. Most of the time.

On some particular systems, namely a Surface Pro 4 and a Surface Pro 3 with Intel Iris 540 / HD 5000 GPUs, both running Windows 10, the following "optimization" breaks rendering.

  • vertex shader:
    • line 13: remove unused out attribute, out vec3 v_position;
    • line 20: change into local var, vec3 _position = a_position;
    • line 23: change to use local var, vec4 position = vec4(_position, 1.0);
  • fragment shader:
    • line 34: remove unused in attribute, in vec3 v_position;

Result is, that on this GPU, it now renders all black. Actually, judging by the output I see it looks like the alpha test fails all the time, discarding all fragments.

On other GPUs (NVidia on Win10/OS X, Intel on OS X) it works as intended.

It's been a horrible exercise to track the problem down this one innocently looking change. Would be nice to get an idea what's wrong about it...

uniform vec3 u_clipMaxs;
uniform vec3 u_clipMins;
void clip(in vec4 worldPosition) {
vec4 p = worldPosition;
gl_ClipDistance[0] = dot(p, vec4(1.0, 0.0, 0.0, -u_clipMins.x));
gl_ClipDistance[1] = dot(p, vec4(-1.0, 0.0, 0.0, u_clipMaxs.x));
gl_ClipDistance[2] = dot(p, vec4(0.0, 1.0, 0.0, -u_clipMins.y));
gl_ClipDistance[3] = dot(p, vec4(0.0, -1.0, 0.0, u_clipMaxs.y));
gl_ClipDistance[4] = dot(p, vec4(0.0, 0.0, 1.0, -u_clipMins.z));
gl_ClipDistance[5] = dot(p, vec4(0.0, 0.0, -1.0, u_clipMaxs.z));
}
/*
vertex shader
*/
#version 140
#pragma gdx include("../lib/clip.glsl")
in vec3 a_position;
in vec3 a_normal;
in vec4 a_color;
out vec3 v_position; // <-- unused, remove this
out vec3 v_normal;
out vec4 v_color;
uniform mat4 u_mvp;
void main() {
v_position = a_position; // <-- change into local var
v_normal = a_normal;
v_color = a_color;
vec4 position = vec4(v_position, 1.0); // <-- use local var
clip(position);
gl_Position = u_mvp * position;
}
/*
fragment shader
*/
#version 140
in vec3 v_position; // <-- unused, remove this
in vec3 v_normal;
in vec4 v_color;
out vec4 f_diffuse;
out vec4 f_normals;
uniform mat4 u_mvp;
void main() {
// color, palette, material
// alpha "test"
float stepAlpha = step(1.0/255.0, v_color.a);
if (stepAlpha < 1.0) {
discard;
}
// lookup color index
float color_index = v_color.r;
float palette_index = v_color.g;
// color index & palette index
f_diffuse = vec4(color_index, palette_index, palette_index * 64.0, v_color.a);
// normals
f_normals = vec4(v_normal.x, 1.0 - v_normal.z, v_normal.y, stepAlpha);
}
/*
vertex shader
*/
#version 140
#pragma gdx include("../lib/clip.glsl")
in vec3 a_position;
in vec3 a_normal;
in vec4 a_color;
out vec3 v_normal;
out vec4 v_color;
uniform mat4 u_mvp;
void main() {
vec3 _position = a_position;
v_normal = a_normal;
v_color = a_color;
vec4 position = vec4(_position, 1.0);
clip(position);
gl_Position = u_mvp * position;
}
/*
fragment shader
*/
#version 140
in vec3 v_normal;
in vec4 v_color;
out vec4 f_diffuse;
out vec4 f_normals;
uniform mat4 u_mvp;
void main() {
// color, palette, material
// alpha "test"
float stepAlpha = step(1.0/255.0, v_color.a);
if (stepAlpha < 1.0) {
discard;
}
// lookup color index
float color_index = v_color.r;
float palette_index = v_color.g;
// color index & palette index
f_diffuse = vec4(color_index, palette_index, palette_index * 64.0, v_color.a);
// normals
f_normals = vec4(v_normal.x, 1.0 - v_normal.z, v_normal.y, stepAlpha);
}
@code-disaster
Copy link
Author

After some shader instruction shuffling... I present The Solution!

not working:

v_normal = a_normal;
v_color = a_color;
vec4 position = vec4(a_position, 1.0);
clip(position);
gl_Position = u_mvp * position;

working:

vec4 position = vec4(a_position, 1.0);
v_normal = a_normal;
v_color = a_color;
clip(position);
gl_Position = u_mvp * position;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment