Weird shadows on custom mesh (Solved)

I have a mesh which I generate for my terrain, but shadows look weird, like this:

Also, when I generate the tangent thingies, I get lots of warnings about Angle between tangets exceeds tolerance for vertex X.

Where should I look to find the problem? the triangles? normals?

I’ll paste code if needed, thanks in advance.

Oh and I have a single DirectionalLight and a DirectionalLightShadowRenderer, with size of 2048 and nbSplits set to 3. EdgeFilteringMode is set to PCF4.

Does the problem go away if you don’t have DirectionalLightShadowRenderer?

If not then it looks like bad normals to be… either way your normals might be bad unless your directional light is pointing straight down. Because that terrain looks pretty unshaded.

Actually normals don’t affect shadows, so fixing thme may not solve your issue.
I see you have a FIlterPostProcessor too, make sure the ShadowRenderer is added before it.

You can ignore the tangent generation warning, it’s unrelated to your issue.

That’s why I qualified the response… if it’s not related to shadow rendering then it’s definitely bad normals… and since it already looks like there are bad normals anyway, it was worth mentioning.

Edit: that being said, from the zoomed in image, the artifacts do look like something the shadow renderer would do. I wonder where the light is because it’s hard to tell because there is no shading at all.

To OP: can you turn on wire frame for your material and show us what your mesh looks like?

…the mesh is not as simple as it appears or I think you would not get the tangent warnings.

Random note: tangents are only necessary for normal mapping or parallax mapping.

Yes the problem only appears with the shadow renderer.

The dlsr processor is added before the water, yes.

Here’s the mesh in wireframe (I disabled water for temporarily):

What is the direction of the light?

Is the mesh using Lighting.j3md or just Unshaded? Or something else?

Using Lighting.j3md, the light direction is set to Vector3f(-0.8f, -0.5f, -0.8f).

what if you normalize the direction? (which you should always do btw)

I do normalize it :stuck_out_tongue:

Here I was thinking that’s just how the shadows looked. Since the temporal fix my shadows have always looked like that :smile:

private void setupLight(Node rootNode) {
    lightDirection = new Vector3f(1, -1, 0).normalizeLocal();
    sun = new DirectionalLight();
    sun.setColor(new ColorRGBA(0.7f, 0.7f, 0.7f, 1.0f));
    AmbientLight ambientLight = new AmbientLight();
    ambientLight.setColor(new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f));

    DirectionalLightShadowRenderer shadowRenderer = new DirectionalLightShadowRenderer(assetManager, 1024, 3) ;

Can you re-phrase that? xD

Ok, so an update here. I was using the Terrain.j3md. I switched to the TerrainLighting.j3md, but I still get the same issue.

The sun light direction is set to new Vector3f(-0.8f, -0.5f, -0.6f).normalizeLocal();

Right now, I’m setting all the normals to 0,1,0.

Again, here is a screenshot:

Some progress!

I seem to have fixed the normals, at least I have improved it:

The code for the normal generation is borrowed from a post here on the forums, it looks like this now:

protected void generateNormals() {
    Vector3f v1,v2,v3,v4,r1,r2,r3,r4,normal;
    for(Vector3f v0 : vertices) {
        normal = new Vector3f();
        System.out.println("Calculating normal for vertex: " + v0);
        //get the 4 neighbouring vertices (north, east, south, west)
        v1 = new Vector3f(v0.x, 0, v0.z - gridSize);
        v2 = new Vector3f(v0.x + gridSize, 0, v0.z);
        v3 = new Vector3f(v0.x, 0, v0.z + gridSize);
        v4 = new Vector3f(v0.x - gridSize, 0, v0.z);
        //get surrounding vertices from terrain data
        v1 = getVertexAt(v1);
        v2 = getVertexAt(v2);
        v3 = getVertexAt(v3);
        v4 = getVertexAt(v4);
        System.out.println("Neighbouring vertices: " + v1 + ", " + v2 + ", " + v3 + ", " + v4);
        if (v1 == null) v1 = new Vector3f(v0.x, v0.y, v0.z - gridSize);
        if (v2 == null) v2 = new Vector3f(v0.x + gridSize, v0.y, v0.z);
        if (v3 == null) v3 = new Vector3f(v0.x, v0.y, v0.z + gridSize);
        if (v4 == null) v4 = new Vector3f(v0.x - gridSize, v0.y, v0.z);

        r1 = v1.cross(v2).normalize();
        r2 = v2.cross(v3).normalize();
        r3 = v3.cross(v4).normalize();
        r4 = v4.cross(v1).normalize();


I think I solved it… It was a SUPER stupid mistake, involving forgetting to .clone() the vertex vector3.