Plane Shadows

Enable basic shadow casting/receiving between objects.

What this code does

- Shadow Mapping: renderer.shadowMap.enabled = true activates shadow rendering.
- DirectionalLight: positioned to cast shadows with light.castShadow = true.
- Shadow Casting: box.castShadow = true makes the cube cast shadows.
- Shadow Receiving: plane.receiveShadow = true makes the ground receive shadows.
- MeshStandardMaterial: responds to lighting and shadows realistically.

JavaScript (plain)

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
camera.position.set(2, 2, 3)

const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.shadowMap.enabled = true
renderer.setSize(width, height)

document.querySelector('#app').appendChild(renderer.domElement)

const controls = new OrbitControls(camera, renderer.domElement)
controls.target.set(0, 0.5, 0)
controls.update()

const plane = new THREE.Mesh(
  new THREE.PlaneGeometry(10, 10),
  new THREE.MeshStandardMaterial({ color: 0x111111 })
)
plane.rotation.x = -Math.PI / 2
plane.receiveShadow = true
scene.add(plane)

const box = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshStandardMaterial({ color: 0x00aaff })
)
box.position.y = 0.5
box.castShadow = true
scene.add(box)

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

function animate() {
  requestAnimationFrame(animate)
  box.rotation.y += 0.01
  controls.update()
  renderer.render(scene, camera)
}
animate()