Add shadow to GLTF model with environment map (RoomEnvironment)

I am trying to add a shadow to a GLTF model. For lighting, I use RoomEnvironment, which, as far as I know, does not support shadows.

So I tried to add this part to my code:

renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

const light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 0, 1, 0 ); 
light.castShadow = true;
scene.add( light );

//obj
obj.castShadow = true; 
obj.receiveShadow = false;

//plane
const planeGeometry = new THREE.PlaneGeometry( 20, 20, 32, 32 );
const planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } )
const plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.receiveShadow = true;
scene.add( plane );

But nothing changes, no shadow appears. I also tried to add the shadow as a new textured object, but it didn’t work either.

My code:

let camera, scene, renderer, obj;
const div = document.querySelector("#obj_3d");

init();
render();

function init() {
  //render
  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(div.devicePixelRatio);
  renderer.setSize(div.offsetWidth, div.offsetHeight);
  renderer.setClearColor(0x000000, 0);
  renderer.toneMapping = THREE.ACESFilmicToneMapping;
  renderer.toneMappingExposure = 1;
  renderer.outputEncoding = THREE.sRGBEncoding;
  renderer.domElement.setAttribute("id", "render");
  div.appendChild(renderer.domElement);

  //camera
  camera = new THREE.PerspectiveCamera(66, div.offsetWidth / div.offsetHeight, 0.1, 2000);
  camera.position.set(0, 0, 1);

  //scene
  const environment = new THREE.RoomEnvironment();
  const pmremGenerator = new THREE.PMREMGenerator(renderer);
  scene = new THREE.Scene();
  scene.environment = pmremGenerator.fromScene(environment).texture;

  //loader
  let loader = new THREE.GLTFLoader();
  loader.load('models/guitar/scene.gltf', function (gltf) {
    obj = gltf.scene;
    obj.rotation.z = 6;
    obj.castShadow = true;
    obj.receiveShadow = false;
    const box = new THREE.Box3().setFromObject(obj);
    const center = box.getCenter(new THREE.Vector3());
    obj.position.x += (obj.position.x - center.x);
    obj.position.y += (obj.position.y - center.y);
    obj.position.z += (obj.position.z - center.z);
    scene.add(obj);
    animate();
  });

  window.addEventListener('resize', onWindowResize);
}

//resize
function onWindowResize() {
  camera.aspect = div.offsetWidth / div.offsetHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(div.offsetWidth, div.offsetHeight);
  renderer.setPixelRatio(div.devicePixelRatio);
  renderer.setSize(div.offsetWidth, div.offsetHeight);
  render();
}

//animate
const clock = new THREE.Clock()
let lastElapsedTime = 0
function animate() {
  const elapsedTime = clock.getElapsedTime()
  const deltaTime = elapsedTime - lastElapsedTime
  lastElapsedTime = elapsedTime
  if (!!obj) {
    obj.position.y = Math.sin(elapsedTime * 1.3) * .05 - 0.1;
  }
  scene.rotation.y -= 0.01;
  requestAnimationFrame(animate);
  render();
}

function render() {
  renderer.render(scene, camera);
}

I am using this model and trying to achieve the same display: Fender Stratocaster Guitar - Download Free 3D model by Ryan_Nein [15a3714] - Sketchfab

Shadows must be allowed not only for the top-most GLTF object, but for all its child meshes. Something like:

obj.traverse( child =>
{
	if( child.isMesh )
	{
		child.castShadow = true;
		child.receiveShadow = true;
	}
} );
1 Like