Perform sampling before branching to discard
This two fragment shaders that exhibit undefined behavior. In GLSL, it is undefined to use implicit or explicit derivatives in non-uniform control flow [1]. The SPIR-V produced by glslang contained similar undefined behavior, which results in incorrect codegen with the amdvlk's LLPC shader compiler, and produces visually incorrect image. This PR fixes this issue by hoisting the sampling so that it's executed before discarding. It's a simple fix and may not be the optimial way to resolve this issue. [1] https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf p. 137.
This commit is contained in:
parent
3977935d94
commit
8982f8f2ec
4 changed files with 11 additions and 3 deletions
|
|
@ -123,17 +123,21 @@ void main(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perform sampling before (potentially) discarding.
|
||||||
|
// This is to avoid implicit derivatives in non-uniform control flow.
|
||||||
|
vec3 normalHeightMapLod = textureLod(sNormalHeightMap, uv, 0.0).rgb;
|
||||||
|
vec3 color = texture(sColorMap, uv).rgb;
|
||||||
|
|
||||||
// Discard fragments at texture border
|
// Discard fragments at texture border
|
||||||
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
|
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 N = normalize(textureLod(sNormalHeightMap, uv, 0.0).rgb * 2.0 - 1.0);
|
vec3 N = normalize(normalHeightMapLod * 2.0 - 1.0);
|
||||||
vec3 L = normalize(inTangentLightPos - inTangentFragPos);
|
vec3 L = normalize(inTangentLightPos - inTangentFragPos);
|
||||||
vec3 R = reflect(-L, N);
|
vec3 R = reflect(-L, N);
|
||||||
vec3 H = normalize(L + V);
|
vec3 H = normalize(L + V);
|
||||||
|
|
||||||
vec3 color = texture(sColorMap, uv).rgb;
|
|
||||||
vec3 ambient = 0.2 * color;
|
vec3 ambient = 0.2 * color;
|
||||||
vec3 diffuse = max(dot(L, N), 0.0) * color;
|
vec3 diffuse = max(dot(L, N), 0.0) * color;
|
||||||
vec3 specular = vec3(0.15) * pow(max(dot(N, H), 0.0), 32.0);
|
vec3 specular = vec3(0.15) * pow(max(dot(N, H), 0.0), 32.0);
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -21,10 +21,14 @@ void main ()
|
||||||
{
|
{
|
||||||
// Sample depth from deferred depth buffer and discard if obscured
|
// Sample depth from deferred depth buffer and discard if obscured
|
||||||
float depth = subpassLoad(samplerPositionDepth).a;
|
float depth = subpassLoad(samplerPositionDepth).a;
|
||||||
|
|
||||||
|
// Save the sampled texture color before discarding.
|
||||||
|
// This is to avoid implicit derivatives in non-uniform control flow.
|
||||||
|
vec4 sampledColor = texture(samplerTexture, inUV);
|
||||||
if ((depth != 0.0) && (linearDepth(gl_FragCoord.z) > depth))
|
if ((depth != 0.0) && (linearDepth(gl_FragCoord.z) > depth))
|
||||||
{
|
{
|
||||||
discard;
|
discard;
|
||||||
};
|
};
|
||||||
|
|
||||||
outColor = texture(samplerTexture, inUV);
|
outColor = sampledColor;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue