You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js无法在平面投射阴影问题求助

Three.js阴影不显示问题修复方案

你的代码里有几个关键问题导致阴影无法显示,修复步骤如下:

  • 修正渲染器阴影启用属性
    原代码中renderer.shadowMap.enable = true是错误的,Three.js中正确的属性名是enabled,需要改为:

    renderer.shadowMap.enabled = true
    
  • 开启点光源的阴影投射
    PointLight默认不会投射阴影,必须手动开启投射开关,同时建议调整光源位置到立方体上方,让阴影清晰显示在平面上:

    // build point light
    pointLight = new THREE.PointLight(0xccffcc, 1, 100)
    pointLight.castShadow = true // 开启阴影投射
    pointLight.position.set(0, 15, 0) // 调整光源到立方体上方
    // 可选:优化阴影贴图清晰度
    pointLight.shadow.mapSize.width = 1024
    pointLight.shadow.mapSize.height = 1024
    scene.add(pointLight)
    

修改后的完整代码:

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

let scene, renderer, camera, cube
let cameraControl
let pointLight, ambientLight, spotLight
let sphereLightMesh
let rotateAngle = 0
let pointLightHelper, cameraHelper

function main() {
    scene = new THREE.Scene() // build scene
    
    renderer = new THREE.WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.shadowMap.enabled = true // 修正属性名
    renderer.shadowMap.type = THREE.PCFSoftShadowMap // 用常量代替数字,可读性更好

    // build camera
    camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000)
    camera.position.set(30, 30, 30)
    camera.lookAt(scene.position)

    // build orbitcontrol
    cameraControl = new OrbitControls(camera, renderer.domElement)
    cameraControl.enableDamping = true
    cameraControl.dampingFactor = 0.25

    // build cube
    const geometry = new THREE.BoxGeometry(6, 6, 6)
    const material = new THREE.MeshPhongMaterial({ color: 0x0000ff })
    cube = new THREE.Mesh(geometry, material)
    cube.position.set(0, 0, 0)
    cube.castShadow = true
    scene.add(cube)

    // build plane
    const planeGeometry = new THREE.PlaneGeometry(60, 60)
    const planeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff })
    let plane = new THREE.Mesh(planeGeometry, planeMaterial)
    plane.rotation.x = -0.5 * Math.PI
    plane.position.set(0, -7, 0)
    plane.receiveShadow = true
    scene.add(plane)

    ambientLight = new THREE.AmbientLight(0x404040)
    scene.add(ambientLight)

    // build point light
    pointLight = new THREE.PointLight(0xccffcc, 1, 100)
    pointLight.castShadow = true
    pointLight.position.set(0, 15, 0)
    pointLight.shadow.mapSize.width = 1024
    pointLight.shadow.mapSize.height = 1024
    scene.add(pointLight)

    document.body.appendChild(renderer.domElement)
}

function render() {
    cameraControl.update()
    requestAnimationFrame(render)
    renderer.render(scene, camera)
}

main()
render()

补充说明:代码里renderer.shadowMap.type = 2替换为THREE.PCFSoftShadowMap后,逻辑不变但可读性更强。

内容的提问来源于stack exchange,提问作者Michael Lin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 04:05:15