Skip to content

Commit

Permalink
Added support for direct3d-like texture coords uv for shadow atlases
Browse files Browse the repository at this point in the history
See http://thedev-log.blogspot.com/2012/07/texture-coordinates-tutorial-opengl-and.html,
the "opengl coordinates" where inverted for proper support of direct3d texture coordinate system.
  • Loading branch information
N8n5h committed Feb 10, 2021
1 parent 1c3e24a commit 5cf0b52
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 12 deletions.
6 changes: 5 additions & 1 deletion Shaders/std/light.glsl
Expand Up @@ -185,13 +185,17 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
vec3 uv = lPos.xyz / lPos.w;
#ifdef _InvY
uv.y = 1.0 - uv.y; // invert Y coordinates for direct3d coordinate system
#endif
direct *= shadowTest(
#ifndef _SingleAtlas
shadowMapAtlasSpot
#else
shadowMapAtlas
#endif
, lPos.xyz / lPos.w, bias
, uv, bias
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
Expand Down
6 changes: 5 additions & 1 deletion Shaders/std/light_mobile.glsl
Expand Up @@ -80,13 +80,17 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
vec3 uv = lPos.xyz / lPos.w;
#ifdef _InvY
uv.y = 1.0 - uv.y; // invert Y coordinates for direct3d coordinate system
#endif
direct *= shadowTest(
#ifndef _SingleAtlas
shadowMapAtlasSpot
#else
shadowMapAtlas
#endif
, lPos.xyz / lPos.w, bias
, uv, bias
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
Expand Down
56 changes: 46 additions & 10 deletions Shaders/std/shadows.glsl
Expand Up @@ -20,7 +20,6 @@ uniform vec2 smSizeUniform;
#endif

#ifdef _ShadowMapAtlas
// https://www.khronos.org/registry/OpenGL/specs/gl/glspec20.pdf // p:168
// https://www.gamedev.net/forums/topic/687535-implementing-a-cube-map-lookup-function/5337472/
vec2 sampleCube(vec3 dir, out int faceIndex) {
vec3 dirAbs = abs(dir);
Expand Down Expand Up @@ -188,40 +187,77 @@ float PCFFakeCube(sampler2DShadow shadowMap, const vec3 lp, vec3 ml, const float
const vec2 uv = sampleCube(ml, faceIndex);

vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
float result = texture(shadowMap, vec3(pointLightTile.z * uv + pointLightTile.xy, compare));
vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
#ifdef _InvY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif

float result = texture(shadowMap, vec3(uvtiled, compare));
// soft shadowing
int newFaceIndex = 0;
vec2 uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 0.0) / smSize)));
uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 0.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _InvY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(pointLightTile.z * uvtiled + pointLightTile.xy, compare));

uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, 1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
result += texture(shadowMap, vec3(pointLightTile.z * uvtiled + pointLightTile.xy, compare));
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _InvY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));

uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
result += texture(shadowMap, vec3(pointLightTile.z * uvtiled + pointLightTile.xy, compare));
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _InvY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));

uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(-1.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
result += texture(shadowMap, vec3(pointLightTile.z * uvtiled + pointLightTile.xy, compare));
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _InvY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));

uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(0.0, 1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
result += texture(shadowMap, vec3(pointLightTile.z * uvtiled + pointLightTile.xy, compare));
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _InvY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));

uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, -1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
result += texture(shadowMap, vec3(pointLightTile.z * uvtiled + pointLightTile.xy, compare));
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _InvY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));

uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, 0.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
result += texture(shadowMap, vec3(pointLightTile.z * uvtiled + pointLightTile.xy, compare));
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _InvY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));

uvtiled = transformOffsetedUV(faceIndex, newFaceIndex, vec2(uv + (vec2(1.0, 1.0) / smSize)));
pointLightTile = pointLightDataArray[lightIndex + newFaceIndex];
result += texture(shadowMap, vec3(pointLightTile.z * uvtiled + pointLightTile.xy, compare));
uvtiled = pointLightTile.z * uvtiled + pointLightTile.xy;
#ifdef _InvY
uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
#endif
result += texture(shadowMap, vec3(uvtiled, compare));

return result / 9.0;
}
Expand Down

0 comments on commit 5cf0b52

Please sign in to comment.