Directional Light and GLTF model not working together

I’m learning three.js and I created a environment with two GLTF models. I placed them together and tried to use a directional light. Here is the code:

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

let scene, camera, renderer, controls, model, model02, directionalLight

// Scene

scene = new THREE.Scene();
scene.background = new THREE.Color(0x06000b)

//Camera
camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 5, 5, 15 );

//Light
directionalLight = new THREE.DirectionalLight(0xffffff, 1)
scene.add(directionalLight)
directionalLight.position.set(10, 10, 10)
directionalLight.target.position.set(0, 0, 0)
scene.add(directionalLight.target)


const helper = new THREE.DirectionalLightHelper( directionalLight, 5 );
scene.add( helper );

//Axes
scene.add(new THREE.AxesHelper(500))

//Renderer
renderer = new THREE.WebGLRenderer();
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

//Controls
controls = new OrbitControls( camera, renderer.domElement );
controls.update();

//Shiba
new GLTFLoader().load( 'models/shiba/scene.gltf', result => {
    model = result.scene
	scene.add( model );
    model.position.set(7, 1, 3)
    scene.add(model)
    animate()

});

//Island
new GLTFLoader().load( 'models/background/bg.gltf', result => {
    model02 = result.scene
    scene.add(model02)
    animate()

});

function animate() {
	requestAnimationFrame( animate );

	// required if controls.enableDamping or controls.autoRotate are set to true
	controls.update();
	renderer.render( scene, camera );
}

I tried to use lights: Directional, Ambient and Spot, but no one has any effect in the models. Can some one help me?

Result:

glTF models generally use THREE.MeshStandardMaterial, which is a physically-based (PBR) material. Metallic PBR materials (material.metalness > 0) require environment maps — not just point, directional, or ambient lighting. You can either create an environment map with THREE.RoomEnvironment as in this example, load one from an HDR or EXR file as in this example, or generate an environment map on the fly with THREE.CubeCamera.

If the materials are non-metallic, then you may just need to increase the brightness of the lights.

2 Likes

I have studied the materials you indicated. Initially, ‘renderer.outputEncoding = THREE.sRGBEncoding;’ solved the problem of the scenery and the dog’s coloring. However, there was still no reflection or interaction with light. So, I created some functions to test reflectivity, such as:

function checkMeshesForLighting(object) {
object.traverse(function (child) {
if (child.isMesh) {
if (child.material.emissive || child.material.color) {
child.castShadow = true;
child.receiveShadow = true;
} else {
console.log("The Mesh " + child.name + " cannot be illuminated.");
}
}
});
}

and

function checkMeshesForReflectivity(object) {
object.traverse(function (child) {
if (child.isMesh) {
if (child.material.reflectivity > 0) {
console.log("The Mesh " + child.name + " reflects light.");
} else {
console.log("The Mesh " + child.name + " does not reflect light.");
}
}
});
}

I had no negative log, but I still could not reflect light. Then I created an environment as indicated, and even though it was present in the logs, there was no interaction with light. Passing the shiba (Dog) to JSX, I discovered the following:

<group {...props} dispose={null} rotation={[0, 0, 0]}>
<mesh geometry={nodes.Group18985_default_0.geometry} material={materials['default']} rotation={[-Math.PI / 2, 0, 0]} />
<mesh geometry={nodes.Box002_default_0.geometry} material={materials['default']} rotation={[-Math.PI / 2, 0, 0]} />
<mesh geometry={nodes.Object001_default_0.geometry} material={materials['default']} rotation={[-Math.PI / 2, 0, 0]} />
</group>

It has the “materials” in default. Finally, I added some materials to the scene with meshphongmaterial, and all of them reacted to light. I understood that many 3D models may not react to light, and in this case, I couldn’t force the 3D to react. However, there are ways to bring saturation to them, which solved my problem.

Thank you for your help! :slight_smile:

I have studied the materials you indicated. Initially, ‘renderer.outputEncoding = THREE.sRGBEncoding;’ solved the problem of the scenery and the dog’s coloring. However, there was still no reflection or interaction with light. So, I created some functions to test reflectivity, such as:

function checkMeshesForLighting(object) {
object.traverse(function (child) {
if (child.isMesh) {
if (child.material.emissive || child.material.color) {
child.castShadow = true;
child.receiveShadow = true;
} else {
console.log("The Mesh " + child.name + " cannot be illuminated.");
}
}
});
}

and

function checkMeshesForReflectivity(object) {
object.traverse(function (child) {
if (child.isMesh) {
if (child.material.reflectivity > 0) {
console.log("The Mesh " + child.name + " reflects light.");
} else {
console.log("The Mesh " + child.name + " does not reflect light.");
}
}
});
}

I had no negative log, but I still could not reflect light. Then I created an environment as indicated, and even though it was present in the logs, there was no interaction with light. Passing the shiba (Dog) to JSX, I discovered the following:

<group {...props} dispose={null} rotation={[0, 0, 0]}>
<mesh geometry={nodes.Group18985_default_0.geometry} material={materials['default']} rotation={[-Math.PI / 2, 0, 0]} />
<mesh geometry={nodes.Box002_default_0.geometry} material={materials['default']} rotation={[-Math.PI / 2, 0, 0]} />
<mesh geometry={nodes.Object001_default_0.geometry} material={materials['default']} rotation={[-Math.PI / 2, 0, 0]} />
</group>

It has the “materials” in default. Finally, I added some materials to the scene with meshphongmaterial, and all of them reacted to light. I understood that many 3D models may not react to light, and in this case, I couldn’t force the 3D to react. However, there are ways to bring saturation to them, which solved my problem.