How to deal with choppy shadows? (light bias is not an issue)


I am trying to figure out how to make shadows look better. Currently they have those weird artifacts I want to get rid of.

I know that I can change the light bias, but it does not help much, because shadows do not look natural with bias and I still have the artifacts in some places.

I think the primary issue is the geometry - it’s really choppy (see: first screenshot, heightmap) - which produces weird looking shadows. Do you have any tips on how should I work with such geometries? Maybe “smoothen” them out or should I just create my own shadows implementation just to handle this case?

I want to solve this issue, but not by changing the light bias. Is there anything else I can try?


Zoomed out:


Have you tried adding a light helper to visualise the shadow camera parameters? The tighter the near far top bottom left and right of the shadow camera, the less area the shadow mapSize is distributed over, default mapSize is 512px so may be worth increasing the height and width. There’s also the option to use pcf soft shadows along with the suggestions above

renderer.shadowMap.type = THREE.PCFSoftShadowMap;

Hey, thanks for you answer.

Yeah, I tried that, also changing the shadowmap size etc, but still no luck.

I start do doubt that there is an easy fix achievable by tweaking some light/mesh parameters, so I would appreciate any ideas. I really want to avoid writing some custom shader just to handle this case.

Ok, I think I figured it out. This screenshot is not the final version (I am still working on it), but I ended up with creating a custom shader that accumulates shadowmaps over multiple frames ( something like this: three.js examples , but it offsets the light source slightly so more of the shadowmap is covered ). I think what is left for me is to tweak the output, blur the shadowmap etc and it’s going to look good. Luckily for me it’s a terrain, so I can then bake in the shadowmap, because it won’t change that often.

Unfortunately I think there is no easy fix / tweak that would solve such artifacts (in case if someone is also trying to solve some similar issue for themselves).

1 Like

how big is your shadowmap? if it’s too small then you will see pixels as blocks stretched over the surface.

Yeah, but I don’t care about pixelation, the banding and those artifacts (checkered pattern) were the issue for me. Thanks for the idea though.

banding is almost always a problem with bias. you said it’s not an issue, you tried negative/positive fractions already?

Maybe choppy because shadow texture pixels stretched.

Thanks for the tips!

Ok, my final version:

Before (Three.js default lights):

Custom shader:

In case someone runs into the similar problem, this is what I ended up using:

  1. This is a really great shader idea I found on shadertoy: Shader - Shadertoy BETA - I started there and modified that shader a bit
  2. I mixed heightmap color with mesh texture color (which prodcues fake SSAO effect - crevices in the terrain are darker)

In the end I have a custom shader material that works well with terrains (but does not work that well with different types of geometries).

The issue is - for some reason THREE.js shadows do not work well with geometries that do not have straight / clearly defined edges and I think there is no fix to that with tweaking some parameters, the only solution is to make something custom for your use case. Shadowmap size, type, light bias etc do not really matter.

1 Like

I still wasn’t quite satisfied, so I came up with something else. Since terrain is static, I used some raytracing and then baked in shadows. I am going for “watercolor paint” texture look. Performs well even on low-end machines. I still do not understand why the original shadows were choppy in the first place.

I am posting this just because I am finally happy with the end result. :slight_smile: Also mountains and desert are procedurally generated. If someone wants to know more on how it’s done or ask some questions, I will be happy to share here.

1 Like