• Advertisement
Sign in to follow this  

Shadowmap not getting projected correctly

This topic is 839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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 :)

Share this post


Link to post
Share on other sites
Advertisement

I'll do it when I'm at my computer again biggrin.png

 

But for now, if it helps:

 

[attachment=29887:scene-marked.png]

 

 

There are a bunch of cubes, and a sphere. Floor is a rectangle. Shadows should be directly below the objects (marked in red) since the light direction is straight down. As I marked, shadows are too far away for some reason (marked in blue).

 

I *think* i'm just sampling the shadowmap at the wrong places, so the shadows get moved around. But I have no idea how "correct" sampling would look. Myabe the framebuffer size vs shadowmap size have something to do with it?

Share this post


Link to post
Share on other sites
What's with the 'new Mat4f' when inverting your view matrix?

Is the 'invView * shadowViewProj' order correct? Which matrix conventions do you use?

Share this post


Link to post
Share on other sites

Along with that, I see in the code that the shadow TC is being biased from from [-1,1] to [0,1]. This is something that's usually messed up so maybe something's wrong there. I also see this being applied to Z which seems wrong to me.

Edited by Styves

Share this post


Link to post
Share on other sites

What's with the 'new Mat4f' when inverting your view matrix?

Java mostly tongue.png Method call is Mat4f.invert(Mat4f destination). Left matrix gets inverted and stored into destination matrix.

 

Is the 'invView * shadowViewProj' order correct? Which matrix conventions do you use?

I'm not sure. It doesn't helps that the variable names are reversed biggrin.png

 

Order is "projection * cameraView * model * position".

 

shadowViewProj is "orthoProjection * lightView * position".

 

So I guess the order for transforming view space position to light view space position is:

 

"orthoProjection * lightView * invCameraView * position"

 

Which as far as I understand, is what I am doing:

.

// shadowViewProj is left, invView is right, invViewShadowProj is destination matrix.
dl.shadowViewProj.mul( invView, dl.invViewShadowProj );

.

Also, I tried creating a window the same size as the shadowmap (1024x1024), now the shadows appear in correct position O_o Look:

.

[attachment=29896:scene-1024-shadowmap.png]

.

Any considerations I should have sampling the shadowmap? (Rescaling the texcoords or something? Maybe the matrix should do it and mine is wrong?)

Share this post


Link to post
Share on other sites


Viewport ?
Yes! Viewport! Saw this thread 15min ago https://www.opengl.org/discussion_boards/showthread.php/189389-Shadow-Mapping-not-working-for-textures-not-size-of-screen

 

He/she is *almost* doing exactly what I was doing ('cept for world space lighting computation).

 

I still can't get rid of the artifacts: Shadows "tremble" when I move the camera, look fine when I stop moving the camera. Progress anyway :D

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement