Three.js 阴影不显示的常见原因与完整解决方案

阿静酱_2382

阿静酱_2382

2026-02-24

360人浏览

原创

Three.js 阴影不显示的常见原因与完整解决方案

本文详解 three.js 中阴影无法渲染的三大典型问题:全局阴影未启用、拼写错误(receiveshadow 误写为 recieveshadow)、语法错误导致脚本中断,并提供可直接运行的修复代码与关键配置要点。

本文详解 three.js 中阴影无法渲染的三大典型问题:全局阴影未启用、拼写错误(receiveshadow 误写为 recieveshadow)、语法错误导致脚本中断,并提供可直接运行的修复代码与关键配置要点。

在 Three.js 中实现真实感阴影看似简单,实则对配置完整性要求极高——哪怕一个拼写错误或一行遗漏,都会导致阴影完全不可见。你提供的代码中,立方体(cube)设置了 castShadow = true,地面(ground)意图启用接收阴影,光源也启用了 castShadow,但阴影仍未出现。根本原因在于三个关键疏漏,下面逐一解析并给出专业级修复方案。

✅ 必须满足的四大阴影前提条件

Three.js 的阴影系统是显式启用的,需同时满足以下四点,缺一不可:

  1. 全局启用阴影渲染器:renderer.shadowMap.enabled = true(必须在渲染循环前设置);
  2. 光源支持阴影投射:light.castShadow = true(且建议调整 shadow.mapSize 提升精度);
  3. 投射物体启用阴影:mesh.castShadow = true;
  4. 接收物体启用阴影接收:mesh.receiveShadow = true(注意拼写:receive,非 recieve)。

⚠️ 特别注意:receiveShadow 是标准属性名,拼错(如 recieveShadow)会导致静默失败——属性被忽略,无控制台报错,极易排查遗漏。

Expanso yaml-to-json
Expanso yaml-to-json

使用 Expanso Edge 管道将 YAML 输入转换为 JSON 格式。

下载

? 修复后的完整可运行代码

以下是修正全部问题(包括删除末尾非法字符 j、修正拼写、补充阴影优化配置)的精简可靠版本:



  <meta charset="utf-8"><title>Three.js Shadow Fix</title><style>body { margin: 0; overflow: hidden; }</style><script async src="https://unpkg.com/es-module-shims@1.10.0/dist/es-module-shims.js"></script><script type="importmap">
{
  "imports": {
    "three": "https://unpkg.com/three@0.163.0/build/three.module.js",
    "three/addons/": "https://unpkg.com/three@0.163.0/examples/jsm/"
  }
}
</script><script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

// 场景、相机、渲染器
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 5, 8);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true; // ✅ 全局启用阴影(关键!)
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 推荐:软阴影更自然
document.body.appendChild(renderer.domElement);

// 控制器
const controls = new OrbitControls(camera, renderer.domElement);

// 立方体(投射阴影)
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true; // ✅ 启用投射
scene.add(cube);

// 方向光(带阴影)
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 10, 7);
light.castShadow = true;
// ? 优化阴影贴图分辨率与投影范围(提升清晰度与稳定性)
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
light.shadow.camera.near = 0.5;
light.shadow.camera.far = 50;
light.shadow.camera.left = -10;
light.shadow.camera.right = 10;
light.shadow.camera.top = 10;
light.shadow.camera.bottom = -10;
scene.add(light);

// 地面(接收阴影)
const groundGeometry = new THREE.PlaneGeometry(10, 10);
const groundMaterial = new THREE.MeshStandardMaterial({ 
  color: 0x0000ff,
  side: THREE.DoubleSide 
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2; // 水平放置
ground.position.y = -3;
ground.receiveShadow = true; // ✅ 正确拼写:receiveShadow(原代码为 recieveShadow ❌)
scene.add(ground);

// 环境光(保证非阴影区可见)
const ambientLight = new THREE.AmbientLight(0x404040, 2);
scene.add(ambientLight);

// 动画循环
function animate() {
  requestAnimationFrame(animate);
  cube.rotation.x += 0.005;
  cube.rotation.y += 0.008;
  renderer.render(scene, camera);
}
animate();

// 响应窗口大小变化
window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>

? 关键注意事项与进阶提示

  • 阴影性能开销大:仅对必要物体启用 castShadow/receiveShadow,避免全场景开启;
  • 阴影贴图尺寸影响质量与内存:light.shadow.mapSize 默认为 512×512,低精度易出现锯齿或“阴影漂移”,建议设为 1024×1024 或更高(但需权衡 GPU 内存);
  • 光源视锥(camera)裁剪范围至关重要:若 light.shadow.camera.far 过小,远处物体将无法生成阴影;过大则降低阴影精度。务必根据场景尺度合理设置 near/far 及 left/right/top/bottom;
  • 材质限制:MeshBasicMaterial 和 MeshDepthMaterial 不支持阴影,必须使用 MeshStandardMaterial、MeshPhongMaterial 等光照计算材质;
  • 调试技巧:临时将 light.shadow.camera.visible = true 并添加 scene.add(light.shadow.camera),可直观查看阴影投射区域是否覆盖目标物体。

遵循以上配置规范,你的 Three.js 场景即可稳定呈现高质量动态阴影。记住:阴影不是“开了就亮”,而是“配对、对齐、调优”的系统工程。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

js

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

2023.06.20

4816

8

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.28

1415

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1878

5

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

2023.08.17

10343

11

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

2023.09.01

1020

4

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

3024

5

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.14

1649

5

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

2023.09.21

5189

3

js生成随机数方法
js生成随机数方法

JavaScript生成随机数的方法,包括使用Math.random()方法生成指定范围内的随机整数、生成随机字符串和生成随机颜色。根据具体需求,可以选择适合的方法来生成随机数,以实现各种功能 。

2023.09.25

3035

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 21.3万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.9万人学习