Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

THREE.js no shadows

Tags:

three.js

I'm currently trying to get into THREE.js a bit and I'm obviously following tutorials and examples but even after all that I can't seem to get shadows working.

shadowMap.enabled is set to true, castShadow is set on the cube beneath the light and receiveShadow is set to true on the floor.

My attempt is visible on https://mroman.ch/shadows/cg.html

image

import * as THREE from "https://threejs.org/build/three.module.js";
import { OrbitControls } from "https://threejs.org/examples/jsm/controls/OrbitControls.js";

function main() {
  const canvas = document.querySelector('#canvas');
  const renderer = new THREE.WebGLRenderer({canvas,'antialias':true});
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.BasicShadowMap;




  const fov = 75;
  const aspect = 1;  
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 8*0.2;
  camera.position.y = 2*0.2;

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

  const sz = 0.2;

  const scene = new THREE.Scene();

  {
    const color = 0xFFFFFF;
    const intensity = 2;
    const light = new THREE.PointLight(color, intensity);
    light.position.set(0, 2*sz, 2*sz);
    light.castShadow = true;
    light.shadow.mapSize.width = 512;
    light.shadow.mapSize.height = 512;
    var d = 200;

    light.shadow.cameraLeft = -d;
    light.shadow.cameraRight = d;
    light.shadow.cameraTop = d;
    light.shadow.cameraBottom = -d;

    light.shadow.camera.far = 1000;

    const helper = new THREE.CameraHelper( light.shadow.camera );
    scene.add( helper );

    scene.add(light);
  }

  const material = new THREE.MeshPhongMaterial({color: "brown"});
  const mat_green = new THREE.MeshPhongMaterial({color:"green"});
  const mat_floor = new THREE.MeshPhongMaterial({color:"gray"});

  const group = new THREE.Group();



  var geometry = new THREE.CylinderGeometry(sz/2,sz/1.5,3*sz,8,8);
  var cube = new THREE.Mesh(geometry, material);
  cube.position.set(0,sz,0);
  group.add(cube);



  geometry = new THREE.BoxGeometry(sz,sz,sz);
  cube = new THREE.Mesh(geometry, mat_green);
  cube.position.set(0.0,3*sz,0);
  group.add(cube);

  geometry = new THREE.IcosahedronGeometry(sz);
  cube = new THREE.Mesh(geometry, mat_green);
  cube.position.set(sz,3*sz,0);
  group.add(cube);

  geometry = new THREE.IcosahedronGeometry(sz);
  cube = new THREE.Mesh(geometry, mat_green);
  cube.position.set(-sz,3*sz,0);
  group.add(cube);

  geometry = new THREE.IcosahedronGeometry(sz);
  cube = new THREE.Mesh(geometry, mat_green);
  cube.position.set(0.0,3*sz,sz);
  group.add(cube);

  geometry = new THREE.IcosahedronGeometry(sz);
  cube = new THREE.Mesh(geometry, mat_green);
  cube.position.set(0.0,3*sz,-sz);
  group.add(cube);

  geometry = new THREE.IcosahedronGeometry(sz);
  cube = new THREE.Mesh(geometry, mat_green);
  cube.position.set(0.0,4*sz,0.0);
  group.add(cube);

  const floor = new THREE.Group();

  for(var x = -4; x <= 4; x++) {
   for(var z = -4; z <= 4; z++) {
     geometry = new THREE.BoxGeometry(sz,sz,sz);
     cube = new THREE.Mesh(geometry, mat_floor);
     cube.position.set(x*sz,-sz,z*sz);
     cube.receiveShadow = true;
     floor.add(cube);
   }
  }



  geometry = new THREE.BoxGeometry(sz, sz, sz);
  cube = new THREE.Mesh(geometry, mat_floor);
  cube.position.set(0,sz,2*sz);
  cube.castShadow = true;
  scene.add(cube);

  scene.add(group);
  scene.add(floor);


  function render(time) {
    controls.update();
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
}

main();

Can anybody point out where I got it wrong?

like image 864
mroman Avatar asked Oct 28 '25 15:10

mroman


1 Answers

Out of curiosity, tried ThreeJs for the first time to answer this question, so might not be good enough in explanation.

Result

Result

To fix cube shadow I changed this:

const light = new THREE.PointLight(color, intensity);
light.position.set(0, 2*sz, 2*sz);

To this:

const light = new THREE.PointLight(color, intensity);
light.position.set(0, 3 * sz, 3 * sz);

I guess it was just issue with light emitter being inside of the cube?

And cylinder just misses property to cast shadow. I would recommend changing cube variable name to something more meaningful.

var geometry = new THREE.CylinderGeometry(sz / 2, sz / 1.5, 3 * sz, 8, 8);
var cube = new THREE.Mesh(geometry, material);
cube.castShadow = true;
like image 83
Yegor Androsov Avatar answered Oct 30 '25 14:10

Yegor Androsov