Agregar sombras en Three.js

Tutorial | Three.js

Código principal

const renderer = new THREE.WebGLRenderer();
renderer.setSize(viewWidth, viewHeight);
// en versiones anteriores no era necesario
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

// agregar cubo
const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshStandardMaterial({color:0x888888})
let cube = new THREE.Mesh(geometry, material)
cube.castShadow = true
cube.position.set(0,0,0)
scene.add(cube)

// agregar luz
let light = new THREE.DirectionalLight(0xffffff,1)
light.position.set(0,1,3)
light.castShadow = true
scene.add(light)

// agregar plano
let planeGeometry = new THREE.PlaneGeometry(20,20,32)
let planeMaterial = new THREE.MeshStandardMaterial({color: 0xffff00})
let plane = new THREE.Mesh(planeGeometry,planeMaterial)
plane.receiveShadow = true;
plane.position.set(0,0,-1)
scene.add(plane)

Código completo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>App</title>
</head>
<body>
    <h1>App</h1>

    <div style="display: flex; justify-content: center;">
        <div id="game"></div>
    </div>

<script type="importmap">
{
    "imports": {
        "three": "https://unpkg.com/three@0.149.0/build/three.module.js"
    }
}
</script>

<script type="module">

import * as THREE from 'three';

// size del la ventana de visualizacion
const viewWidth = 360;
const viewHeight = 360;

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(viewWidth, viewHeight);
// en versiones anteriores no era necesario
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

// agregar en el div
let game_div = document.getElementById("game");
game_div.appendChild(renderer.domElement);

// agregar cubo
const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshStandardMaterial({color:0x888888})
let cube = new THREE.Mesh(geometry, material)
cube.castShadow = true
cube.position.set(0,0,0)
scene.add(cube)

// opcional: agregar tres cubos mas
add_cubes(scene);

// agregar luz
let light = new THREE.DirectionalLight(0xffffff,1)
light.position.set(0,1,3)
light.castShadow = true
scene.add(light)

// agregar plano
let planeGeometry = new THREE.PlaneGeometry(20,20,32)
let planeMaterial = new THREE.MeshStandardMaterial({color: 0xffff00})
let plane = new THREE.Mesh(planeGeometry,planeMaterial)
plane.receiveShadow = true;
plane.position.set(0,0,-1)
scene.add(plane)

// mover la camara
camera.position.set(0,-2,5)
camera.rotation.set(0.6,0,0.5)

function animate(){
    requestAnimationFrame(animate);
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
    renderer.render(scene, camera);
}

function add_cubes(scene){
    const geometry = new THREE.BoxGeometry();
    const material1 = new THREE.MeshStandardMaterial({color:0xff0000});
    const material2 = new THREE.MeshStandardMaterial({color:0x00ff00});
    const material3 = new THREE.MeshStandardMaterial({color:0x0000ff});
    let cube1 = new THREE.Mesh(geometry, material1);
    let cube2 = new THREE.Mesh(geometry, material2);
    let cube3 = new THREE.Mesh(geometry, material3);
    cube1.castShadow = true
    cube2.castShadow = true
    cube3.castShadow = true
    scene.add(cube1);
    scene.add(cube2);
    scene.add(cube3);

    cube1.position.x = 5
    cube2.position.y = 5
    cube3.position.z = 5
}
animate();
</script>

</body>
</html>

Referencias

Tutorial | Three.js