Exporting Blender Scene - Lighting Issues

Hi there,

Thanks for welcoming me into the forum.

I’m new to THREE and I’m wondering if you could help with a problem that I’m facing with importing a scene from blender. The lighting seems to be quite off, I have tried to reposition the camera before adding the scene but to no avail.
Attached the screenshots of blender & what is rendering in chrome as well as code.

Any help greatly appreciated!


**
 *  THREE.js
 *
 */

//Scene, Camera & Renderer
let scene = new THREE.Scene(),
    camera = null,
    renderer = new THREE.WebGLRenderer({antialias: true, alpha: true}),
    loader = new GLTFLoader();

//Render and append child
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
document.querySelector('.hero-canvas').appendChild(renderer.domElement);

loader.load(
    'shapes/hero-scene1.glb',
    function(gltf) {
        
        camera = gltf.cameras[0];
        scene.add(gltf.scene);
        
        updateCamera();
        animate();

    }, function(progress) {
        // console.log(progress);
    }, function (error) {
        // console.error(error);
    });

//Main animate function
let animate = () => {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
};

//Update camera
let updateCamera = () => {
    camera.updateProjectionMatrix();
};

//Update canvas on resize
window.addEventListener('resize', () => {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
});!

Can you please share hero-scene1.glb in this topic?

In general, the lighting in Blender and three.js can vary quite noticeable. You might get better results by not exporting any lights and setup the lighting in three.js via code instead.

A recommended basic setup for a model viewer is the addition of an ambient and point light like so:

const ambientLight = new THREE.AmbientLight( 0xffffff, 0.4 );
scene.add( ambientLight );

const pointLight = new THREE.PointLight( 0xffffff, 0.6 );
camera.add( pointLight );
scene.add( camera );
1 Like

Hi @Mugen87

Many thanks for your reply.

Attached is hero-scene1.glb.
I am able to use the lights in three but they never seem to be the same.

Thanks again.

hero-scene1.glb (19.7 KB)

Well, there are two directional lights in your scene after importing the glb file. Like I said before, this setup won’t produce similar results like in Blender. You should at least add an ambient light and lower the intensity values of the directional lights a bit.

Hm, if it doesn’t then that’s a bug I’m not yet aware of. glTF allows point, spot, and directional lights. Some of Blender’s settings can’t be exported (specular, and shadow-related options like radius) but those that are should match reasonably well. For that to work, you will need to configure your renderer:

renderer.outputEncoding = THREE.sRGBEncoding;
renderer.physicallyCorrectLights = true;

… however, in this case that isn’t fixing the problem, and even on my viewer with IBL disabled I see the same problem. Couple questions:

  1. Can you share the .blend?
  2. Have you disabled all other lights in Blender? And previewed in Viewport Shading mode?
  3. The normals on these models look odd to me… you might want hard normals on the bottom vertices? I manually fixed the cylinder in the screenshot below, compare that to the base of the blue shape:

But even with the normals fixed, it seems like there’s no lighting for one side of the shape. I wonder if Blender has also included an IBL.

1 Like

Hi @donmccurdy @Mugen87

Many thanks for your replies.

I have tried to change the render settings as above but no avail.

The .blend file is attached, that viewer is great.

hero-scene1.blend (737.6 KB)

Note i have tried to disable the lights & import but can’t get it right in three. Not sure what the ibl is?

Ok, this comes down to two issues:

  1. Blender’s preview appears to include IBL (image based lighting, also called an environment map), or something like it, and I don’t know how to disable that… as a result, your two lights are not actually the only two light sources in Blender. Surfaces facing away from those two lights look well-lit in Blender, but won’t in other viewers unless you add IBL, or even just an ambient light, to compensate.

  2. The normals don’t appear to be exporting quite right, and the vertices along hard edges at the tops and bottoms of shapes are being smoothed. That might be a bug in the Blender exporter, or a mistake in the model, I’m not sure. Consider filing an issue at https://github.com/KhronosGroup/glTF-Blender-IO. You can see the issue plainly in BabylonJS by enabling the normal debug mode:

This causes the dark areas on the lower halves of each model. You can work around it by putting a loop cut next to each hard edge, in Blender, as shown here:

I did so for just the green shape, and you’ll see that its lighting is fixed in both threejs and babylonjs. Without IBL, the green shape is darker on the unlit side (but not the entire bottom half of the shape). With IBL, the green shape looks entirely correct to me, although normals on the top surface still aren’t quite perfect.

lighting three.js babylonjs
no IBL Screen Shot 2020-01-08 at 10.58.25 AM Screen Shot 2020-01-08 at 10.58.29 AM
IBL Screen Shot 2020-01-08 at 10.58.16 AM Screen Shot 2020-01-08 at 10.58.06 AM
4 Likes