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

Three.js场景中如何让平面接收球体投射的阴影?

Three.js平面接收球体阴影问题修复

下面是代码中导致阴影不显示的问题及修复方案:

问题点与修复步骤

  • Renderer阴影启用错误:代码中renderer.shadowMap.enable = true是错误写法,正确属性为enabled
  • 方向光阴影相机范围未配置:DirectionalLight的阴影相机默认视锥体范围过小,无法覆盖场景中的物体,需手动调整参数
  • 球体颜色值无效:0xffff00f是非法十六进制颜色值,应改为0xffff00

修复后的完整代码

//.................SETUP................//
import {
    WebGLRenderer,
    PerspectiveCamera,
    Scene,
    BoxGeometry,
    MeshBasicMaterial,
    Mesh,
    Group,
    PlaneGeometry,
    AxesHelper,
    GridHelper,
    DoubleSide,
    DirectionalLight,
    AmbientLight,
    MeshStandardMaterial,
    DirectionalLightHelper,
    Fog,
    TextureLoader,
    CubeTextureLoader,
    SphereGeometry,
    PCFSoftShadowMap,
    CameraHelper
} from './three.module.js';
import { OrbitControls } from './q.js';
//................PROGRAM...............//
var renderer, camera, scene, light, light1, geometry, material, mesh;
// renderer
renderer = new WebGLRenderer({canvas:
document.getElementById('Canvas'), antialias: true, alpha: true});
//alpha: true 让画布透明,显示下层HTML内容
renderer.setClearColor(0x555555);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// 修复阴影启用属性
renderer.shadowMap.enabled = true;
// 使用软阴影提升视觉效果
renderer.shadowMap.type = PCFSoftShadowMap;
// camera
camera = new PerspectiveCamera(35, window.innerWidth / 
window.innerHeight, 0.1, 6000);
camera.position.set(0, 0, 100);
camera.lookAt(0, 0, 0);
//controls
var orbitcontrol = new OrbitControls(camera, renderer.domElement)
//scene
scene = new Scene();
//lights
//var ambientlight = new AmbientLight(0x333333);
//scene.add(ambientlight);
var sun = new DirectionalLight(0xffffff, 0.8);
sun.castShadow = true;
scene.add(sun);
sun.position.set(0, 40, 0);

// 配置方向光阴影相机参数,覆盖场景物体范围
sun.shadow.camera.left = -50;
sun.shadow.camera.right = 50;
sun.shadow.camera.top = 50;
sun.shadow.camera.bottom = -50;
sun.shadow.camera.near = 0.1;
sun.shadow.camera.far = 100;
// 添加阴影相机助手,方便调试(可根据需求移除)
scene.add(new CameraHelper(sun.shadow.camera));

//fog
//scene.fog = new Fog(0xffffff, 0, 200); 
//helpers
var gridhelper = new GridHelper(10, 10);
scene.add(gridhelper);
var axishelper = new AxesHelper(3);
scene.add(axishelper);
var directionallighthelper = new DirectionalLightHelper(sun, 10, 0xff0000);
scene.add(directionallighthelper);
//material loaders
var bildimport = new TextureLoader().load('a.jpg');
var bildimport2 = new TextureLoader().load('träd.jpg');
var textureLoader = new TextureLoader();
scene.background = textureLoader.load('a.jpg');
//objects
  //sphere
  var geometrySphere = new SphereGeometry(10, 15);
  var materialSphere = new MeshStandardMaterial({
    // 修复无效颜色值
    color: 0xffff00,
    flatShading: true, 
    //wireframe: true, 
  });
  var meshSphere = new Mesh(geometrySphere, materialSphere);
  scene.add(meshSphere);
  meshSphere.position.set(0,20,0);
  meshSphere.castShadow = true;
  meshSphere.receiveShadow = true;
  //cube
geometry = new BoxGeometry(1, 1, 1);
var alt_material = [
  new MeshBasicMaterial({map: bildimport2}),
  new MeshBasicMaterial({map: bildimport}),
  new MeshBasicMaterial({map: bildimport2}),
  new MeshBasicMaterial({map: bildimport}),
  new MeshBasicMaterial({map: bildimport2}),
  new MeshBasicMaterial({map: bildimport}),
];
material = new MeshStandardMaterial({
    color: 0xff0000,
    map: bildimport2,
});
mesh = new Mesh(geometry, alt_material);
mesh.position.set(0, 50, 0);
mesh.castShadow = true;
scene.add(mesh);
  //plane
var geometry2 = new PlaneGeometry(50, 50); 
var material2 = new MeshStandardMaterial({
    color: 0xfff00,
    map: bildimport,
    side: DoubleSide,  // 让平面双面着色
});
var mesh2 = new Mesh(geometry2, material2);
mesh2.receiveShadow = true;
scene.add(mesh2);
mesh2.rotation.x = -0.5 * Math.PI;
//groups
//renderer loop 
requestAnimationFrame(render);
var i = 0;
var increase_of_i = 0.01;
function render() {
  mesh.rotation.x += 0.01;
  mesh.rotation.y += 0.01;
 // mesh.position.y = 100 * Math.abs(Math.sin(i));
  mesh.scale.x = 1 + Math.abs(Math.sin(2*i));
  mesh.scale.y = 1 + Math.abs(Math.sin(2*i));
  mesh.scale.z = 1 + Math.abs(Math.sin(2*i));
  i += increase_of_i;
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

额外说明

  • 阴影相机助手可直观显示阴影有效范围,调试完成后可移除
  • 只有支持光照的材质(如MeshStandardMaterial)能参与阴影计算,MeshBasicMaterial不支持光照和阴影
  • 若阴影清晰度不足,可调整sun.shadow.mapSize参数,比如设置为new THREE.Vector2(2048, 2048)提升分辨率

内容的提问来源于stack exchange,提问作者William Gustafsson Knutsson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:15:37