当前位置: 首页 > article >正文

Three.js 阴影 (Shadow) 知识点整理

阴影主要由 castShadowreceiveShadow 控制,并通过不同类型的光源 (DirectionalLightSpotLightPointLight) 生成。我们将系统地整理与阴影相关的知识点。


1️⃣ 基础概念

  • castShadow 🎭:物体是否投射阴影。
  • receiveShadow 🏞️:物体是否接收阴影。
  • renderer.shadowMap.enabled = true ✅:全局开启阴影渲染。
  • renderer.shadowMap.type 📦:设置阴影质量,常见类型:
    • THREE.BasicShadowMap(性能高但质量低)
    • THREE.PCFShadowMap(平滑阴影,默认值)
    • THREE.PCFSoftShadowMap(更柔和的阴影)
    • THREE.VSMShadowMap(高级阴影,适用于柔和阴影)

2️⃣ 各类光源的阴影设置

在 Three.js 中,不是所有的光源都能投射阴影:

光源类型

支持阴影

代码示例

DirectionalLight

✅ 支持

directionalLight.castShadow = true

SpotLight

✅ 支持

spotLight.castShadow = true

PointLight

✅ 支持

pointLight.castShadow = true

AmbientLight

❌ 不支持

HemisphereLight

❌ 不支持

RectAreaLight

❌ 不支持


3️⃣ 代码分析:Directional Light 阴影

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(2, 2, -1);
scene.add(directionalLight);

directionalLight.castShadow = true; // ✅ 允许投射阴影

// 调整阴影贴图大小,影响阴影清晰度
directionalLight.shadow.mapSize.width = 1024;
directionalLight.shadow.mapSize.height = 1024;

// 调整阴影相机视锥体,决定阴影投射区域
directionalLight.shadow.camera.top = 2;
directionalLight.shadow.camera.bottom = -2;
directionalLight.shadow.camera.right = 2;
directionalLight.shadow.camera.left = -2;

// 调整相机的远近平面,影响阴影范围
directionalLight.shadow.camera.near = 1;
directionalLight.shadow.camera.far = 6;

// 创建 CameraHelper 可视化阴影相机
const directionalLightHelper = new THREE.CameraHelper(directionalLight.shadow.camera);
scene.add(directionalLightHelper);

📌 重点知识

  • shadow.mapSize:控制阴影贴图分辨率,越大阴影越清晰,但影响性能。
  • shadow.camera.top/bottom/left/right:控制阴影的投影区域,过大会导致阴影模糊,过小会裁剪阴影。
  • shadow.camera.near/far:控制阴影投射的最近和最远范围,合理调整可优化阴影效果。

4️⃣ 代码分析:Spot Light 阴影

const spotLight = new THREE.SpotLight(0xffffff, 20, 5, Math.PI * 0.3);
spotLight.position.set(0, 2, 2);
spotLight.castShadow = true; // ✅ 允许投射阴影

// 调整阴影质量
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;

// 控制阴影相机的远近平面
spotLight.shadow.camera.fov = 30;
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 6;

scene.add(spotLight);
scene.add(spotLight.target);

// 创建 CameraHelper 可视化阴影相机
const spotLightHelper = new THREE.CameraHelper(spotLight.shadow.camera);
scene.add(spotLightHelper);

📌 重点知识

  • shadow.camera.fov:影响光锥大小,控制阴影范围。
  • shadow.camera.near/far:控制阴影渲染范围,避免不必要的计算。
  • spotLight.target:聚光灯照射的目标点,影响阴影方向。

5️⃣ 代码分析:Point Light 阴影

const pointLight = new THREE.PointLight(0xffffff, 3);
pointLight.position.set(-1, 1, 0);
pointLight.castShadow = true; // ✅ 允许投射阴影

// 调整阴影质量
pointLight.shadow.mapSize.width = 1024;
pointLight.shadow.mapSize.height = 1024;

// 控制阴影相机的远近平面
pointLight.shadow.camera.near = 0.1;
pointLight.shadow.camera.far = 6;

scene.add(pointLight);

// 创建 CameraHelper 可视化阴影相机
const pointLightHelper = new THREE.CameraHelper(pointLight.shadow.camera);
scene.add(pointLightHelper);

📌 重点知识

  • PointLight 采用 cubeShadowMap:需要渲染 6 个方向的阴影,性能开销较大。
  • shadow.camera.near/far:优化阴影投射范围,避免性能浪费。

6️⃣ 代码分析:阴影贴图

const textureLoader = new THREE.TextureLoader();
const bakedShadow = textureLoader.load('texture/shadow/bakedShadow.jpg');
const simpleShadow = textureLoader.load('texture/shadow/simpleShadow.jpg');

📌 重点知识

  • 预渲染阴影贴图(Baked Shadow):避免实时计算阴影,提高性能。
  • 透明阴影(Simple Shadow)
new THREE.MeshBasicMaterial({
    color: 0x000000,
    transparent: true,
    alphaMap: simpleShadow
})
    • transparent: true 让黑色区域可见,白色区域透明。
    • alphaMap 让阴影贴图应用到 PlaneGeometry

7️⃣ 代码分析:球体阴影

sphereshadow.rotation.x = -Math.PI * 0.5;
sphereshadow.position.y = plane.position.y + 0.01;
scene.add(sphere, plane, sphereshadow);

📌 重点知识

  • 手动调整阴影位置 避免阴影和地面重叠导致视觉错误。
  • 动态改变阴影透明度
sphereshadow.material.opacity = 1 - sphere.position.y * 0.3;
    • 球体越高,阴影越淡,实现“动态阴影”效果。

8️⃣ 代码分析:阴影优化

renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

📌 重点知识

  • PCFSoftShadowMap:提供平滑柔和的阴影。
  • setPixelRatio(Math.min(window.devicePixelRatio, 2)):限制像素比,平衡清晰度和性能。

🔚 总结

知识点

关键参数

开启阴影

renderer.shadowMap.enabled = true

光源投射阴影

light.castShadow = true

物体投射阴影

mesh.castShadow = true

物体接收阴影

mesh.receiveShadow = true

优化阴影

shadow.mapSize

, shadow.camera.near/far

手动优化阴影效果

预渲染贴图 (bakedShadow

), PCFSoftShadowMap

🚀 通过合理调整这些参数,可以让 Three.js 的阴影更加逼真、柔和,同时兼顾性能优化!


http://www.kler.cn/a/588797.html

相关文章:

  • Node.js 与 MongoDB:高效的企业级应用开发
  • 如何使用IDEA Maven构建本地jar包和POM文件?
  • 【C++多线程】thread
  • SpringBoot动态加载JAR包实战:实现插件化架构的终极指南
  • 全球领先的光学方案设计公司:倚光科技
  • 【QT笔记---QText】
  • Android Dagger2 框架编译时注解处理模块深度剖析(二)
  • 简单爬虫--框架
  • 用户身份认证与令牌管理全解析:从原理到分布式实践
  • 每日Attention学习26——Dynamic Weighted Feature Fusion
  • 泽众TestOne推出快速测试用例设计,让自动化更快捷
  • Keytool常见问题全解析:从环境配置到公钥提取
  • Advanced Intelligent Systems 软体机器手助力截肢者玩转鼠标
  • DeepSeek-R1思路训练多模态大模型-Vision-R1开源及实现方法思路
  • JavaScript相关面试题
  • 前端面试题---vue项目打包时, 内存不足了怎么办 为什么会出现这样的情况
  • Web开发-PHP应用文件操作安全上传下载任意读取删除目录遍历文件包含
  • 深入解析工厂模式及其C#实现
  • 【k8s002】k8s健康检查与故障诊断
  • Ubuntu下安装后anaconda出现conda:command not found