Point-light shadows with setRadius()

I need some brainstorming help here.

While porting my MazeGame app to the ARM-based Mac Mini, I noticed that the shadows looked corrupt. I boiled the issue down to a simple test case, which renders differently on the Mac than on Linux, but I don’t understand why.

Here’s a Linux screenshot:

Here’s a MacOS screenshot:

Here’s the test app:

import com.jme3.app.SimpleApplication;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.material.Materials;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.jme3.shadow.PointLightShadowRenderer;

public class MazeGame extends SimpleApplication {

    public static void main(String[] arguments) {
        MazeGame application = new MazeGame();
        application.setShowSettings(false);
        application.start();
    }

    @Override
    public void simpleInitApp() {
        cam.setLocation(new Vector3f(-35f, 5f, 30f));
        cam.lookAtDirection(Vector3f.UNIT_X, Vector3f.UNIT_Y);
        flyCam.setEnabled(false);

        viewPort.setBackgroundColor(new ColorRGBA(0f, 0f, 1f, 0f));
        rootNode.setShadowMode(ShadowMode.CastAndReceive);

        PointLight torch = new PointLight();
        rootNode.addLight(torch);
        torch.setColor(new ColorRGBA(1f, 1f, 1f, 1f));
        torch.setPosition(new Vector3f(3f, 4.65f, 33f));
        torch.setRadius(1000f);

        Material material = new Material(assetManager, Materials.LIGHTING);
        material.setBoolean("UseMaterialColors", true);
        material.setColor("Diffuse", new ColorRGBA(1f, 1f, 1f, 1f));
        material.setColor("Specular", new ColorRGBA(1f, 1f, 1f, 1f));
        material.setFloat("Shininess", 1f);

        Quad mesh = new Quad(10f, 10f);
        Geometry geometry = new Geometry("", mesh);
        rootNode.attachChild(geometry);
        geometry.move(-5f, 10f, 25f);
        geometry.rotate(FastMath.HALF_PI, 0f, 0f);
        geometry.setMaterial(material);

        PointLightShadowRenderer plsr
                = new PointLightShadowRenderer(assetManager, 256);
        plsr.setLight(torch);
        plsr.setShadowIntensity(1f);
        viewPort.addProcessor(plsr);
    }
}

Note that if I comment out the torch.setRadius(1000f) line, the issue goes away.

Any suggestions where to look for the cause of this issue?

I think it disappears when you remove setRadius, because the shadow renderer uses the light radius to set the frustum of its internal cams. The default radius is 0 if not set, so it will “disable” the effect by culling all the scene away.

It seems somehow (??) the scene has something that project a shadow on macos… or it might be a corruption happening in the shader (eg. variables not initialized to zero, invalid math).

1 Like

This would be my bet. Macs have always been super-sensitive to that.

sgold, are you using nvidia on your Linux box? (if so, further evidence because on a scale, nvidia has historically behaved the best in the case of improperly setup variables and attributes.)

1 Like

Yeah, the Linux box has a 2012-era NVIDIA graphics adapter:

Mar 14, 2022 12:30:14 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFO: LWJGL 3.3.0 build 21 context running on thread jME3 Main
 * Graphics Adapter: GLFW 3.4.0 Wayland X11 GLX Null EGL OSMesa monotonic shared
Mar 14, 2022 12:30:15 PM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: NVIDIA Corporation
 * Renderer: GeForce GT 545/PCIe/SSE2
 * OpenGL Version: 4.6.0 NVIDIA 390.144
 * GLSL Version: 4.60 NVIDIA
 * Profile: Compatibility

The only caster in the scene is the geometry that’s receiving the shadows. When I change its ShadowMode to Receive, the issue goes away—as if it were casting a shadow on itself. I don’t know what mechanisms prevent self-shadowing in JME3.

I stared at “Shadows.glsllib” and couldn’t make any sense of it.

I opened issue 1783 so this doesn’t get forgotten.

If you think of any experiments that might narrow down the issue, let me know.

1 Like

Oh, this narrows down the issue a lot. It might be a precision related issue when comparing shadow maps and depth, can you try to switch the shadow compare mode from software to hardware or vice-versa and see if one of the two solves the issue?

2 Likes

Thanks for the suggestion.

The default shadow-compare mode on both systems is Hardware. Setting the compare mode to Software had no visible effect: still no shadow on Linux and a garbled shadow on macOS.

Edit: Another clue … I recently enabled flycam and saw that shadow pattern changes rapidly as the camera rotates and/or translates. It resembles the video “snow” (noise) on an old black-and-white television that’s not tuned to a station.