Sign in to follow this  
Modestas Andrijauskas

Shadow mapping problems

Recommended Posts

Hello! Yesterday and today I was thinking where is the problem with lighting and shadows, but today when I disabled lighting I noticed that the problem is with shadow mapping. I've never had this problem before, but here's how it looks:

 

ss02_51_08.png

 

As you can see cube casts good shadow, but it has some self shadowing problems itself, and you can clearly see the same problem with terrain. Why this problem occurs?

Share this post


Link to post
Share on other sites

shadpow map bias whenever you put a shadow fragment in the fragment shader you bias it with a small value that removes self shadowing, i believe that your problem your bias val is not big enough to cover floating point inaccuracies

Share this post


Link to post
Share on other sites

As WiredCat said, applying small bias to shadow map should help a little, but it looks like, you've got no diffuse light.

Adding light should help, becouse you should have low light in places where you can see bias(back faces of meshes from view point of light).

Share this post


Link to post
Share on other sites

Lighting maybe helps a little bit: http://s1.postimg.org/iw9gcncnz/ss05_07_11.png

And adding 0.0005 bias helps even more: http://s3.postimg.org/q103n8ern/ss05_08_55.png but it doesn't for cube (look at the edges, there is small amount of shadow): http://s17.postimg.org/itae40u0f/ss05_09_11.png

Edited by Modestas

Share this post


Link to post
Share on other sites

additionally you wil have to fix light projection matrix , you could even use two different for terrain and box since they have differnet sizes)

 

(you must find proper z near z far value for both objects) and use that in sahder because with one shadowmap simply box is too small to be properly shaded (flaoting point precision problem)

Share this post


Link to post
Share on other sites

additionally you wil have to fix light projection matrix , you could even use two different for terrain and box since they have differnet sizes)

 

(you must find proper z near z far value for both objects) and use that in sahder because with one shadowmap simply box is too small to be properly shaded (flaoting point precision problem)

I was changing z near and far, but couldn't find proper. 

 

The shadow map should be generated using back-faces.


L. Spiro

I know, and I'm always generating shadow map with back-faces only.

 

I've been reading about cascaded shadow maps and here is a quote from nvidia pdf about cascaded shadow maps:

CSM are usually used for shadows cast by the sun over a large terrain. 

 

So I think I should implement CSM in my game, but couldn't find good tutorial about it. I think I need to make the thing that was explained by MJP in this topic: http://www.gamedev.net/topic/505893-orthographic-projection-for-shadow-mapping/#entry4299499 2nd post, and to make cascaded shadow maps just increase camera z position to create more orthographic projections for further distances, am I correct?

Share this post


Link to post
Share on other sites
1) the most important thing you can do is to make sure the shadowmap projection min/max Z is clamped within the viewable frustum. This hugely increases the useful shadowmap z precision, allowing you to eliminate shadow acne with smaller bias values, which in turn reduces peter panning. (You also need to turn on depth clamping during render)

Any shadow casters closer to the light than the viewable volume are just clamped to minz, since the place the shadow starts isnt visible anyhow. For CPU frustum culling during shadowmap rendering, however, you need to extend only the light frustum used for culling towards the light to catch all shadow casters.

2) you can adjust the bias value based on the surface normal vs light dir incident angle. Steeper angles need higher bias values, while surfaces perpendicular to the light need little bias.

3) if your meshes are wellformed, you can write only backfaces to the shadowmap, avoiding bias problems for any "thick" areas of objects.

4) never consult the shadowmap for surfaces which you calculate are backface to the light.. Since you already know they are in shadow geometrically.

You can see implementations for all these techniques, as well as parallel split shadow maps, in my free educational 3d engine, simplescene.

https://github.com/jeske/SimpleScene

Share this post


Link to post
Share on other sites

I've actually found my problem, but can't remember in what website it was described. The problem is that orthogonal (or not, can't remember) faces should not be lit by light, but they are. There was another problem with lighting, source vector was wrong and after fixing it, now it looks like this: http://s10.postimg.org/7kot0nleh/ss11_01_21.png

 

As you can see there is only like 1-3 triangles that are having problem with shadowing, and for me it looks like they are orthogonal to the directional light. I've found my problem described in stackoverflow http://stackoverflow.com/questions/13371893/shadow-mapping-artifacts-on-thin-wall-orthogonal-to-light In the answer is said to make sure that face is facing the light and do it by checking if dot of normal is greater than epsilon, so I think it's same as checking if face is orthogonal to light. But how I would do that? I can't check if dot of normal is greater than epsilon, because dot function takes 2 parameters and not 1, what should be second parameter?

Edited by Modestas

Share this post


Link to post
Share on other sites

 

what should be second parameter?

The direction of the light.


L. Spiro

 

 

This one: 

if(dot(norm, s) < 0.05)

didn't helped, but this: 

if(max(dot(norm, s), 0.0) < 0.05)

helped, until I didn't looked at other places, for example top of the hill was not lit by the light, where it should. So this is not the right way as a solution.

Share this post


Link to post
Share on other sites
abs(dot(norm, s)) < 0.05

This problem seems to be unique to you. You seem to have custom preferences on what should cast shadows and what should not, as this is not-at-all standard practice and will definitely cause artifacts with moving suns.


L. Spiro Edited by L. Spiro

Share this post


Link to post
Share on other sites

abs(dot(norm, s)) < 0.05

This problem seems to be unique to you. You seem to have custom preferences on what should cast shadows and what should not, as this is not-at-all standard practice and will definitely cause artifacts with moving suns.


L. Spiro

 

I think I should ignore this thing (do not lit surfaces which normals are orthogonal to the light). As you said this problem seems unique to me, so yeah I found out that my bias matrix is wrong, instead of this:

0.5 0.0 0.0 0.0
0.0 0.5 0.0 0.0
0.0 0.0 0.5 0.0
0.5 0.5 0.5 1.0

I've had this:

0.5 0.0 0.0 0.5
0.0 0.5 0.0 0.5
0.0 0.0 0.5 0.5
0.0 0.0 0.0 1.0

But after correcting bias matrix everything got screwed up, and now I can think of one problem, matrices multiplication, I think I did it wrong. My program is written in Java and using LWJGL library, there is a matrix class with multiply function and I think I'm multiplying it wrong. By reading shadow mapping tutorial, my light's matrix should be computed like this:

lightMatrix = bias * projection * view * model

Function for multiply looks like this:

public static Matrix4f mul(Matrix4f left, Matrix4f right, Matrix4f dest) 

It multiplies right matrix by left matrix and stores to the dest matrix.

For testing purposes I set light projection matrix to perspective, and this is how I multiply them():

Matrix4f.mul(projectionMatrix, biasMatrix, lightViewProjectionMatrix);
Matrix4f.mul(viewMatrix, lightViewProjectionMatrix, lightViewProjectionMatrix);

//After every model transform I send this matrix to the shader:
Matrix4f matrix = new Matrix4f();
Matrix4f.mul(modelMatrix, lightViewProjectionMatrix, matrix);

And the only thing that I get is just black line across the terrain

 

EDIT: It's not the bias problem, I tried to calculate matrices in vertex shader to make sure bias matrix is correct and results were same.

Edited by Modestas

Share this post


Link to post
Share on other sites
It sounds like something bigger is wrong.. Perhaps the vectors you are dotting are not in the same coordinate space?

A good way to debug lighting is to render debugging colors that clearly show what is happening.

Make a lighting debug shader (or mode) which renders green for lit surfaces, red for surfaces backfacing the light, and yellow for surfaces lit but shadowed by the shadowmap.

P.s. "orthogonal" is not the right word for surfaces backfacing the light.. They are just unlit or backfacing. Orthogonal vectors are vectors with no commonality. Perpendicular vectors are orthogonal. For example, the unit x and unit y vectors are orthogonal.

Share this post


Link to post
Share on other sites

abs(dot(norm, s)) < 0.05

This problem seems to be unique to you. You seem to have custom preferences on what should cast shadows and what should not, as this is not-at-all standard practice and will definitely cause artifacts with moving suns.


L. Spiro

As I said bias wasn't the problem, so I tried this, and still no changes.

 

 

It sounds like something bigger is wrong.. Perhaps the vectors you are dotting are not in the same coordinate space?

A good way to debug lighting is to render debugging colors that clearly show what is happening.

Make a lighting debug shader (or mode) which renders green for lit surfaces, red for surfaces backfacing the light, and yellow for surfaces lit but shadowed by the shadowmap.

P.s. "orthogonal" is not the right word for surfaces backfacing the light.. They are just unlit or backfacing. Orthogonal vectors are vectors with no commonality. Perpendicular vectors are orthogonal. For example, the unit x and unit y vectors are orthogonal.

 

Light's direction vector is in eye space, and normal vector I think is also in eye space, because in vertex shader it's multiplied by normal matrix and normalized, so they are in same coordinate space. 

 

I'm actually not sure how to debug lighting, but I tried things that you said. Here is the screenshot how diffuse and ambient lighting looks (red is ambient, pink is diffuse): http://s18.postimg.org/f2zv74a15/ss09_01_11.png and here is lighting with shadow mapping: http://s23.postimg.org/vlywtvg2j/ss09_01_13.png

 

The only thing I know, is that the part where is diffuse lighting between shadow and ambient lighting, is the part where lighting transitions from ambient to diffuse and this is the problem, but I dunno how to fix this problem. 

Share this post


Link to post
Share on other sites

Something is wrong with either your terminology, or the way you are thinking about lighting.

All lit surfaces include ambient/emissive and diffuse and specular lighting terms. Unlit surfaces receive only ambient/emissive terms.

Your terrain screenshots would be easier to understand with wireframes, and with more contrasting colors used. (use red for lit, green for unlit)

If you want more detailed help, post a link to your code..

Edited by DaveSF

Share this post


Link to post
Share on other sites

Okay, here is screenshots with wireframes, and more contrasting colors, lit surfaces red, unlit green: http://s11.postimg.org/fj7kr4b1v/ss01_41_07.png  and here is shadow mapping, shadowed surfaces black, and not shadowed white: http://s14.postimg.org/4gfhevan5/ss01_40_56.png

 

I would give you all project files, but it would be mess for you, because you wouldn't know where what is. I can give you some parts of code e.g. lighting and shadow mapping including shaders. Or you could connect to my pc via teamviewer, and I would show you where all needed code is.

 

P.s. I was thinking about shadow mapping technique that I'm using. In my previous project (accidentally cleared my whole hdd and lost it..) I used different shadow mapping technique and as far as I remember shadow mapping for monkey head were pretty nice, and now I added monkey head to current project and it doesn't looks good. Maybe that's the problem? Currently I do shadow mapping with these texture parameters:

glTexParameteri(GL_TEXTURE_2D, GL14.GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL14.GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);

So in fragment shader I can use sampler2DShadow and this is how I render shadows

float shadow = textureProj(ShadowMap, ShadowCoord);
FragColor = diffuse * shadow + ambient;

And in previous project it was done differently. I didn't used those texture parameters and instead of sampler2DShadow I used sampler2D. It was actually code from Fabien Sanglard, this article: http://fabiensanglard.net/shadowmapping/ Maybe I should try switching my shadow mapping technique to that, which Fabien Sanglard showed?

Share this post


Link to post
Share on other sites
To me, your lit/unlit screenshot looks wrong. There is no light direction that could cause the green areas to be backfacing while adjacent triangles with nearly the same normal would be front facing.

Fix this before you do anything else.

Is it possible your surface normals are being computed wrong? Draw the vertex normals with gl-lines to debug them.

Then...

bool FrontFacing = dot(surface_normal, light_dir) > 0;

You should get into the habit of using hosted source control, such as github. Then you won't lose anything if you lose a hdd, and you can let someone help by looking at your files.

Share this post


Link to post
Share on other sites

Omg.. In blender you can set shading to smooth or flat, I've been using smooth shading because it looked better when lit, and that caused the problem. Here is how it looks with smooth shading: http://s14.postimg.org/6j0rtch1t/ss03_23_39.png and flat: http://s9.postimg.org/55a6z76rj/ss03_23_42.png  With flat shading shadow looks better, but how then I would make surfaces look smoother without smooth shading?

Share this post


Link to post
Share on other sites

It's pretty much impossible for us to understand static terrain screenshots lighting like that. They need to have wireframes, or texture, or a video and motion -- something to help us visually understand them, and we need to know how they are being rendered. (just forward lighting? forward + shadow mapping?) 

 

I don't understand why the flat shaded one looks better. Because the small shadowmap-acne artifact disappears? 

 

If you have a blender file, then it sounds like what you are rendering is just a mesh (not a generated heightmap terrain). Have you tried rendering it in blender? You could set it up for GLSL viewport rendering, or even render it raytraced to get an idea what it should look like. 

 

Can you share the blender file you are using? Perhaps that would clarify what is going on. 

Edited by DaveSF

Share this post


Link to post
Share on other sites

Yes, because small shadowmap-acne artifact disappears. Here is the blender file: http://www14.zippyshare.com/v/shvo4v1l/file.html I didn't tried to render it in blender, because all I can do with blender, just make some model and export it to obj file, nothing else. And if you still wanna take a look at screenshots with wireframes, here you go: http://s10.postimg.org/55ub72q09/ss01_30_53.png http://s23.postimg.org/xnija6qm3/ss01_30_55.png

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this