Glb imported model does not support ambient light

Background

I’ve been creating models in blender exporting them as gltf 2.0 format and then loading them into jmonkey. I’ve noticed the material these models are loaded with is “Common/MatDefs/Light/PBRLighting.j3md” instead of “Common/MatDefs/Light/Lighting.j3md”. This seems to work fine with point lights, but not ambient lights.

E.g. if I make a simple cube in blender, export it in gltf 2.0 format including its materials then load it into an application with some ambient and point lights

public class SimpleLitCube extends SimpleApplication{
    public static void main(String[] args){
        SimpleLitCube app = new SimpleLitCube();
        app.start();
    }

    @Override
    public void simpleInitApp(){
        Spatial simpleCube = getAssetManager().loadModel("Models/simpleCube.glb");
        rootNode.attachChild(simpleCube);

        AmbientLight al = new AmbientLight();
        al.setColor(ColorRGBA.White.mult(0.3f));
        getRootNode().addLight(al);

        PointLight light = new PointLight();
        light.setPosition(new Vector3f(10, 10, 10));
        light.setRadius(1000);
        light.setColor(ColorRGBA.White);
        rootNode.addLight(light);
    }
}

It looks like this

image

The point lights are clearly lighting the surface but the ambient light is being ignored. If I change the material to “Common/MatDefs/Light/Lighting.j3md” it behaves the way I’d expect

image

Question

What’s the right way to deal with materials and glb imports. I had intended to have models with their own embedded materials and just load them but should I be using the glb just for the mesh and attach the material myself in code?

For materials using PbrLighting.j3md, the AmbientLight is only used to scale the LightProbe. So if the scene doesn’t have a LightProbe then an AmbientLight doesn’t light anything at all.

Adding a light probe (such as the one named defaultProbe.j3o that you can find in the jme3-testdata library) should make it work.

1 Like

So that does work, based on jmonkeyengine/RefEnv.java at master · jMonkeyEngine/jmonkeyengine · GitHub

@Override
public void simpleInitApp(){
    .....
    stateManager.attach(new EnvironmentCamera(256, Vector3f.ZERO));
}

@Override
public void update(){
    super.update();
    frame++;
    if (frame == 2){
        EnvironmentCamera eCam = stateManager.getState(EnvironmentCamera.class);

        // Create a LightProbe
        LightProbe probe = LightProbeFactory.makeProbe(eCam, rootNode, EnvMapUtils.GenerationType.Fast, new JobProgressAdapter<>(){

            @Override
            public void done(LightProbe result){
                System.err.println("Done rendering env maps");
                tex = EnvMapUtils.getCubeMapCrossDebugViewWithMipMaps(result.getPrefilteredEnvMap(), assetManager);
                rootNode.getChild(0).setCullHint(Spatial.CullHint.Dynamic);
            }
        });
        probe.getArea().setRadius(100);
        rootNode.addLight(probe);
    }


}

Does it matter where I place the probe? Do I need more than 1?

And do I ever need to update it? Moving the cube seemed to get its lighting right

Maybe. Depends on the scene and the probe. For generated probes, I would say “probably”.

Again, depends on the scene and the probe.

Same.

If your materials are highly reflective (mirror like finish) and/or your scene is really varied then light probe placement and update is going to be more important. (Up to you what “more important” means.) Plenty of games do not update their reflections.

Personally, I prefer to keep my reflective objects somewhat muted and just use one of a set of a standard light probes instead of a generated one. But it depends on the scene, etc. see above.

1 Like

Perhaps the problem is I don’t really understand what a light probe is even for so im struggling to make decisions on what to do with them (beyond it doesnt work properly without them). I couldnt find any wiki articles on them. Some forum conversations seemed to treat them as sort-of precalculated light (but that seems to conflict with the idea of standard probes)

(I am kind of leaning towards replacing the materials with lighting.j3md as thats what im more familiar with using)

1 Like

A light probe is a cubeMap based 360 degree snapshot of a scene that is used for faking indirect lighting and reflections

There are these 3 articles that were written about PBR by the dev who made the JME implemention, they’re not the best for explaining how to use PBR and light probes but there unfortunately is not any better PBR documentation yet. Physically Based Rendering – Part one :: jMonkeyEngine Docs

You can use pre-rendered lightProbes (like this one https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-testdata/src/main/resources/Scenes/defaultProbe.j3o)

Or you can also generate your own light probes based on your game’s unique scenes using jme’s LightProbeFactory but this process can take more than a few seconds, since its just taking a 360 degree snapshot around the camera and rendering it to a cubeMap, so generating probes is best done ahead of time while designing your scenes rather than at run time most of the time.

Each geometry using PbrLighting.j3md can have up to 3 light probes max, and if there’s more than one it will blend them together smoothly based on each probe’s location and radius. So you typically want to set up your probe in a specific location with a specific radius to cover the area that it matches. For example, a snowy forest would have its own light probe, and a green jungly forest next to it would have a seperate light probe. And then the light probes would slightly overlap where the 2 forest edges meet so the lighting blends smoothly between the areas with different lighting.

1 Like

Ok, so the light probe looks in all directions and records what it sees as a cubemap. Then this cubemap is used to light objects (so the reflected light off an object becomes a new light source). I can imagine how that would get the reflected light correct for objects near the lightprobe’s position, but shouldn’t it get it horribly wrong for anywhere else?

(And in that context what can a default probe mean, is it just a gradient of most light comes from the sky with some-but-less from lower down?)

Or should the light probe be pre baked only with far parts of the scene, not the “furniture”. And used for “smarter-ambient-light”

[Side note, isn’t the jme3-testdata repo not intended to be used in real applications, due to being huge]

1 Like

To most of your questions, the answers are all “it depends”. If none of your objects are particularly shiny then it won’t matter much.

Default light probes are kind of like “environment maps” in the old days. They approximate some common lighting setups. This is similar to the default environments that Blender has available in its rendering options.

Here are a list of some default probe thumbnails to see what I mean. The j3os are nearby:

1 Like

That’s helpful, they all kind of look like skyboxes which tallies with my mental model (that at least within some region need to be treated as if they are at infinite range)

It depends on the scene.

For an indoor space, the studio probe is probably a better choice. (Or even the bathroom, stations, etc. probes if you want more ambient color variation and don’t have mirror-surfaces.)

You can get away with a lot of sin if you stick to brushed metal surfaces instead of mirror-metal surfaces.