Hi, so this is the issue:
.
Scene picture
.
[attachment=29883:scene.png]
.
Shadowmap picture
.
[attachment=29884:shadowmap.png]
.
As you can see in the scene pic, the shadowmap isn't getting projected correctly. The directional light is straight down on the Y axis. The sphere shadow should appear right next to the rightmost cube, and the cube shadows should appear below them.
.
Shadowmap size is 1024x1024, screen size is 1280x720. I'm thinking it has something to do with that but I'm not terribly sure how to rescale the tex coords.
.
Its a deferred setup, view space position gets computed from the depth buffer.
.
This is my entire directional light fragment shader:
.
// Input parameters.
in vec2 passTexCoord;
// Output parameters.
layout ( location = RT_0 ) out vec3 outLightAcc;
// G Buffer texture samplers.
SAMPLING(gbAlbedo, SMP_RT, 2D, 0);
SAMPLING(gbNormal, SMP_RT, 2D, 1);
SAMPLING(gbMisc, SMP_RT, 2D, 2);
SAMPLING(gbDepth, SMP_RT, 2D, 3);
SAMPLING(gbShadowmap, SMP_RT, 2D, 4);
USING(UBO, DIRLIGHT);
USING(UBO, VIEWRAY);
USING(UBO, FRUSTUM);
void main ( void )
{
// Fetch shininess value.
float shininess = texture(gbMisc, passTexCoord).x;
// Fetch albedo texel.
vec4 txAlbedo = texture(gbAlbedo, passTexCoord).xyzw;
// Fetch specular intensity.
float specIntensity = txAlbedo.w;
// Fetch g buffer normal and decode it.
vec3 normal = decodeNormal(texture(gbNormal, passTexCoord).xy);
// Fetch depth and compute view space position.
vec3 viewPos = computeViewPos(frustum, viewRays, passTexCoord, texture(gbDepth, passTexCoord).x);
// Compute position in light space.
vec4 tmpLightSpacePos = dirLight.invViewShadowProj * vec4(viewPos, 1.0);
vec3 lightSpacePos = tmpLightSpacePos.xyz / tmpLightSpacePos.w;
vec2 shadowmapCoords = lightSpacePos.xy * 0.5 + 0.5;
float lightSpaceDepth = lightSpacePos.z * 0.5 + 0.5;
float shadowDepth = texture2D(gbShadowmap, shadowmapCoords).x;
float inShadow = max(0.2, float(lightSpaceDepth < shadowDepth));
// View space light direction.
vec3 lightDir = normalize(dirLight.viewDir.xyz);
// Light color
vec3 lightColor = dirLight.color.xyz;
// Cos angle incidence of light.
float cosAngle = dot( normal, lightDir );
// Influence factor to lerp for hemispheric ambient.
float influence = dot( normal, vec3(0, 1.0, 0) ) * 0.5 + 0.5;
// Diffuse light term.
vec3 diffuse = max(0.0, cosAngle ) * lightColor;
// Specular term.
vec3 specular = computeSpecular(viewPos, lightDir, normal, specIntensity, shininess) * lightColor;
// Hemisperic ambient term.
vec3 ambient = mix( dirLight.groundColor.xyz, dirLight.skyColor.xyz, influence ) * lightColor;
outLightAcc = (txAlbedo.xyz * diffuse + specular) * inShadow + ambient;
}
.
The code for computing the "invViewShadowProj" matrix is the following:
.
// Computing the shadowmap generation matrix:
private final void computeShadowViewProj ( final DirectionalLight dl )
{
final Mat4f tmp = dl.shadowViewProj;
final Vec3f dir = new Vec3f( dl.worldDirection ).negate();
// Fixed bounding box for now.
float size = 50;
// Left, right, bottom, top, znear, zfar.
tmp.setOrtho( -size, size, -size, size, -size, size);
// Target, "up" vector. Up cant be (0,1,0) because target would be parallel.
tmp.lookAlong( dir, new Vec3f( 0, 0, 1 ) );
}
// Compute view space position to light space position matrix
private final void computeInvViewShadowProj ( final DirectionalLight dl )
{
final Mat4f view = cameras.getUnsafe( cameraEntities.getUnsafe( 0 ) ).viewTransform;
final Mat4f invView = view.invert( new Mat4f() );
// shadowViewProj is left, invView is right, invViewShadowProj is destination matrix.
dl.shadowViewProj.mul( invView, dl.invViewShadowProj );
}
.
Any help is appreciated :)