flickering shadow problem

Hello,

As always i vertex parent the sun to my character box.
While it’s vertex parented to it’s dead center(not on a corner of the box) i don’t have a clue why the shadows flicker so much on walls.

Is there a solution for this flickering shadows?
(baking is no option, i am using dynamic lights (lamps/sun) and the world gets libloaded+random generated)

Video:
As you can see it already starts out with the building to be dark, if i move the mouse a tiny bit it will act normal (figuring it has to do with libload(async) and the camera/player is not moving so it can’t calculate the building) but why can it calculate the ground, trees, etc, but not the building?

https://youtu.be/HQX51E6ce88

Also what i like to know is, is there an option (build-in) already to stop the light bleeding through walls?.

Yay, another person who does loading screens! Loaders unite!

Also what i like to know is, is there an option (build-in) already to stop the light bleeding through walls?.

Yes! Decrease the shadow bias and increase the bleed bias. This will likely also solve the flickering. So try it first.

The flickering is caused by aliasing/pixellation on the depth map - as you move the mouse slightly the position of the aliasing artifacts also moves and creates the flicker.
You could try making your walls thicker so the inner walls are always away from the aliasing artefacts.
You could try using PCF3 sampling (in UPBGE)
You could try using variance shadows
You could try lowering your shadow resolution if it’s already variance.

Another solution is instead of vertex parenting the lamp to the player, use a script that looks like:


lamp = ....
player = ....
lamp.worldPosition.x = int(player.worldPosition.x)
lamp.worldPosition.y = int(player.worldPosition.y)

This way the lamp moves in discrete increments and is largely free from flickering (except when the player is on the boundary between two ‘snapped’ positions). Or you could make it move to the players position only every second or two - this is probably a better solution.

Decrease the shadow bias and increase the bleed bias

Normally if i change those the shadows get ugly, like wierd lines etc.

I will try it it out tomorrow, thanks.

This looks similar to a problem I was having, though I’m not completely sure. I just switched from multi-texture to GLSL rendering

It’s not the same, you got an alpha problem, i got issues with shadows :wink:

I tried a few things:

You could try making your walls thicker so the inner walls are always away from the aliasing artefacts

This works for 50% half the walls are good aand the other half stays the same.

You could try using PCF3 sampling (in UPBGE)

I dont use UPbge.

You could try using variance shadows

This only works for 50% big object has shadows while smaller object loses its shadow.

You could try lowering your shadow resolution if it’s already variance.

if i lower it, the shadows getting uglier, atm shadows are 2048 with 30 frustum and 50 range.

lamp = …player = …
lamp.worldPosition.x = int(player.worldPosition.x) lamp.worldPosition.y = int(player.worldPosition.y)

I needed the use the copy() option, the shadows are way better, but still not good, now the walls gained other shadow glitches.

#edit:
here is a video:

the change in brightness come due to my lightmanager, using 2 lamps 3 light sources the lamps switches locations, but as you can see, the buildup or how you wanna call it acting strange.

At 0:21 I see geometry issues rather than lighting issues. That’s z-depth fighting because of two overlapping face.

At 0:37 you see the light snapping position. You can mitigate this by aligning the pixels with the snap distance. So currently (if you use my snap code) it moves in increments of 1bu. This means that if you want it to be unnoticeable, you need to ensure there is an even number of pixels per blender unit. So currently you have 2048 pixels over 30 blender units. This gives 68.26666666 pixels per blender unit frustum. If you change your frustum to 32 units square, then you get a round 64 pixels per blender unit, and this snapping issue should go away.

You will still get diagonal lines across your walls, they just won’t move.

To get rid of the diagonal lines, you’ll have to make sure that your roof extends past the edges of your walls, and seals with them (shared edge). I also see some walls are zero thickness. This isn’t helping anything. Even if you plan to have end-pieces sealing them off, this can still cause shadow issues due to floating point precision resulting in the walls not quite sealing. So give those interior walls and the roof some thickness. (Some decent thickness, maybe 0.05bu minimum). On a side note: anyone know the bit depth used for the shadow maps? Because this gets mapped over the shadow camera’s depth range, and is what determines how thin the geometry can be.

blender has badly bugged shadows (flickering, jumping) since 2.77 i think. upbge has fixed it. it will happen every once in a while in 2.74, but only briefly on start.

https://developer.blender.org/T48256

@Daedalus:
I have not had issues with shadows unless the camera is facing along a cardinal axis. (Don’t ask me why). The issues shown here aren’t the whole shadows flickering, but are small artefacts.

At 0:21 I see geometry issues rather than lighting issues. That’s z-depth fighting because of two overlapping face.

yes true, i extruded the walls to see if the problem went away, it does for 50%, so yes the side of the inside wall shines trough.
(just a test blend, and that is not the issue here)

At 0:37 you see the light snapping position. You can mitigate this by aligning the pixels with the snap distance. So currently (if you use my snap code) it moves in increments of 1bu. This means that if you want it to be unnoticeable, you need to ensure there is an even number of pixels per blender unit. So currently you have 2048 pixels over 30 blender units. This gives 68.26666666 pixels per blender unit frustum. If you change your frustum to 32 units square, then you get a round 64 pixels per blender unit, and this snapping issue should go away.

Yes this is the issue i was talking about. I did some more testing and i found out it has nothing to do with the building, thickness, or settings of the sun lamp, the problem is in the sunlamps light/shadow casting direction. what do i mean?

The sun lamp was just shining on the y axis, all walls that where aligned to that axis gained the issue.
i rotated the building and the problem was gone. Hmmm… so i changed everything back to how i had it in the first place, but now i did not rotate the building but rotated the sun, problem gone! :smiley:

At first i thought that it had something to do with thickness, this is not true, and for this setup i tried both (also with your setup/advice) and there is no difference, only thing is on a thin wall you loose the dept with the issue (screenshots below).

I also tested if it had to do with backface culling (why not right? it could be) but it wasn’t.

It is purely how the sun/lamp is shining on the object, so after testing for 3 hours to find a solution, i can say the fix is to rotate the sun/lamp on its z axis.

Now with that problem out of my way, i really want know the way to stop light from bleeding trough walls, if it is possible at all
(screenshot below).

To get rid of the diagonal lines, you’ll have to make sure that your roof extends past the edges of your walls, and seals with them (shared edge). I also see some walls are zero thickness

Hmm, i always use a cube for buildings, make an opening in it for the door and that’s it, so its still a closed cube.

On a side note: anyone know the bit depth used for the shadow maps? Because this gets mapped over the shadow camera’s depth range, and is what determines how thin the geometry can be.

No clue at all, but just a plane as wall works, atleast in my case.

Thanks for the help so far, hopefully there is a way to stop the bleeding.




make your buildings architectually correct with 3d walls and ceilings.

Perhaps we should take some time to revise how shadows actually work, then you can solve these issues yourself (and understand why thickness is a must)

Each shadow is actually a camera. For a spot light, the camera has perspective. For a sun lamp, the camera is orthographic.
First the camera renders a depth buffer. This is a greyscale image that shows a picture of the closest geometry, with the value being it’s distance from the camera.
Then the depth buffer is projected onto the scene.
Inside each objects fragment shader, this depth map is sampled, and the distance from the light measured. If the distance is less, then the object is not in shadow. If the distance is more, then the object is in shadow.

The issue comes for the object that is not in shadow. This is because the depth in the shadow map is equal to that distance from the camera, but because of the precision of the depth map and the finite number of pixels in it, at sharp angles you get things like this:



This is because the depth map can be pictured as lots of slices, each one bit of precision apart. At one end of them you may be behind it, and at the other end you’re in front of it. I’m calling these jaggies

Similarly, this happens on the other side of the plane as well - with the light penetrating slightly (bleed):


To solve the first problem (which lets face it, is the most major one), most game engines introduce an offset to their shadow maps - effectively shifting the depth buffer slightly further away from the camera. This removes the first issue, but makes the second one slightly worse. In BGE, this is known as the bias
Here’s a shot of the vertical plane with some bias, you can see the light is penetrating:


Unfortunately, there is no way to solve both issues. You cannot have no bleed and no jaggies. Higher resolution images makes the jaggies smaller by reducing the pixel size. Reducing the clipping distances of the light help things out by making the jaggies closer together.

More coming in the next post with more images…

So what can you do to solve this? Give your geometry thickness. how thick? We can calculate the distance (for an orthographic light) given the resolution and the frustum size. We know from before that your shadow map has 64 pixels per blender unit. This means that, in theory, with no mipmapping of the shadow map, the jaggies will be 1/64 bu perpendicular to the direction of the lamp. Parallel to the lamp? I’m not sure how big they are. I have yet to figure out quite how depth buffers are stored. In some quick tests I did, this was (for sane distances), smaller than caused by the resolution.
However, we also have to take the angle of the surface into account. At very shallow angles, the 1/64 bu will be stretched. How far? It’s a tangental relationship. (1/64) * tan(angle_from_perpendicular). This means if it’s vertical, (0 degrees) then the resolution will cause no jaggies. If it’s parallel, then it will cause infinitely long ones. At 45 degrees, the jaggies will be 1/64bu both in length and height.

So I got out blender’s ruler and measured it (this is a 45 degree angle):


Note that I’m sampling a single pixel - ignoring the effects of lerping between the pixels. It comes to 0.018, pretty close to 1/64 (which is 0.0155). But you can clearly see the jaggies appear bigger than that. This is because the pixel map is linearly interpolated between pixels. As a result, they double in size! Ouch.

So if your lamp is at 45 degrees to your geometry, you need a wall thickness of 1/32. Having the wall twice the size of the resolution per pixel will work nicely if no geometry is more oblique to the light than 45 degrees. This allows the jaggies can fit safely in the middle of the wall never to be seen. But what about the bias value? This is calculated in screen-space, so you can’t just set it to 1/64 and hope for the best. It’s a function of the near and far clip of the camera, and I’m not familiar with the math behind depth maps. So my advice is to make a simple scene where the jaggies can be clearly seen, and adjust the bias until they are inside the walls.

But we are not projecting shadows onto a flat plane - some geometry will be oblique. What can we do? Well, one technique is to make the shadow map bias dependant on normal angle - something that youle was experimenting with in UPBGE at one point (no idea if it made it into master). But for simple shadows, there’s not much you can do except increase the wall thickness and increase the bias to match.

But remember, it’s a tangental relationship, and as the angle goes towards 90 degrees, the jaggy size goes towards infinity. So with a simple shadow, it is impossible to remove them completely. But we can use some tricks.
We can shadow our nearly oblique walls from the sun using … a roof! This way the walls are already in shadow, and you don’t have artifacts on them to worry about. This only works with more vertical sun’s, but here’s a shot showing both artifacts and the effects of a roof (with thickness):


If we twiddle the camera’s clipping plane so we can have a look inside the roof, you can see the jaggies are safely hidden away by the roofs thickness:


So if the sun can be high enough, put eaves on your building, and make the roof thick enough to hide the jaggies, and no-one will notice anything out of place.

@sdfgeoff

Thanks for the information this explains lot.
Ok, so i went into blender again and test a few things out once again :slight_smile:

I can now see exactly what you mean/meant.
i have created a test blend: shadow test.blend (1.06 MB)

This blend has different buildings, build in different ways.
Best solution is indeed to use cube for walls/roof/floor/etc. and not a single cube for all.

One thing i noticed is that you need to place the roof inside the walls?(last picture you posted)
in my blend the roof is just touching the wall (like if it is done with snapping(did it manual)) and it absorbs the light bleed into the roof.

Ok, now that i know this i can rebuild all my buildings in my projects, that’s the bad part… lol.
also it goes from low poly to medium poly count, but meh… computers these days can handle a lot more then that.

Thanks both of you.

One thing i noticed is that you need to place the roof inside the walls?(last picture you posted)
in my blend the roof is just touching the wall (like if it is done with snapping(did it manual)) and it absorbs the light bleed into the roof.

You do not need to have the wall protruding into the roof. It was intersecting because:

  1. I was lazy
  2. It shows that the artefacts are still there, I haven’t hit some magic button to make them go away.

Thankfully light bleed is not like water, and you don’t need to soak it up with a cloth!

also it goes from low poly to medium poly count, but meh… computers these days can handle a lot more then that.

Shader complexity and object count have far more impact than poly count- at least on these scales. (10’s - 100’s of polies). So keep the building as one mesh, (You can join meshes with ctrl+J)
But yeah, that won’t stop you needing to rebuild a whole bunch of models. Edge split + solidify may do what you want.

Thankfully light bleed is not like water, and you don’t need to soak it up with a cloth!

Haha indeed, but still it’s something else if you always used a cube as a building :stuck_out_tongue:

So keep the building as one mesh, (You can join meshes with ctrl+J)
But yeah, that won’t stop you needing to rebuild a whole bunch of models. Edge split + solidify may do what you want.

hmm i could use edge split, but like my example blend solidify is not a good option to use.
i know i can join meshes and ofc i am already doing that, but none the less it stays extra work to do :S

but i will manage haha, thanks for all the info.