7.Three.js 中 CubeCamera详解与实战示例

🧩 示例效果演示


CubeCamera是Three.js中一个非常有趣且实用的工具!它可以帮我们实现动态环境映射(比如让一个金属球实时反射周围环境 ✨),打造超酷炫的视觉效果!

今天我们就来超详细 讲解一下 CubeCamera 的概念、应用场景、使用方式,并给出完整示例代码!

保证让你轻松掌握~🎯


🧠 CubeCamera是什么?

一句话理解

👉 CubeCamera是一个可以生成六个方向立方体贴图的摄像机,常用于制作动态反射效果!

  • 它内部实际上是通过同时拍摄六个方向(前、后、左、右、上、下 📸)来生成一张立方体纹理

  • 这张立方体纹理可以被物体用作环境贴图(envMap) ,实现实时反射效果。💎

🔵 官方定义

THREE.CubeCamera(near, far, cubeRenderTarget)


🌍 CubeCamera应用场景

常见使用场景包括:

  • 🪞 镜面反射效果(金属球体、镜子等)

  • 🌎 动态环境反射(比如水面、玻璃材质)

  • 🚗 游戏中汽车表面的真实反射

  • 🏙️ 建筑可视化中的动态玻璃幕墙

只要你想要一个随着环境变化而变化的反射效果,CubeCamera就是你的神器!✨


📦 CubeCamera核心属性

属性 说明
near 摄像机近裁剪面(通常设小一点,比如 1)
far 摄像机远裁剪面(通常设远一点,比如 1000)
renderTarget 渲染的目标对象,内部存储六个方向的画面
update(renderer, scene) 更新立方体纹理,需要每帧调用

🔥 最简单的使用流程

来看看CubeCamera的基本使用套路 🛠️:

javascript 复制代码
// 引入Three.js
import * as THREE from './libs/three.module.js';

// 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xeeeeee);

// 创建主摄像机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 2000);
camera.position.set(0, 10, 30);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 添加光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);
scene.add(ambientLight);

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

// 添加一些简单的环境物体
const boxGeometry = new THREE.BoxGeometry(10, 10, 10);
const boxMaterial = new THREE.MeshStandardMaterial({ color: 0xff6666 });
const box = new THREE.Mesh(boxGeometry, boxMaterial);
box.position.set(-15, 0, 0);
scene.add(box);

const planeGeometry = new THREE.PlaneGeometry(200, 200);
const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x999999 });
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2;
scene.add(plane);

// 创建 CubeCamera
const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256, {
  format: THREE.RGBAFormat,
  generateMipmaps: true,
  minFilter: THREE.LinearMipmapLinearFilter
});
const cubeCamera = new THREE.CubeCamera(1, 1000, cubeRenderTarget);
scene.add(cubeCamera);

// 创建反射材质的小球
const sphereMaterial = new THREE.MeshBasicMaterial({
  envMap: cubeRenderTarget.texture
});
const sphere = new THREE.Mesh(
  new THREE.SphereGeometry(5, 32, 32),
  sphereMaterial
);
sphere.position.set(0, 5, 0);
scene.add(sphere);

// 动画循环
function animate() {
  requestAnimationFrame(animate);

  // 让场景物体转动
  box.rotation.y += 0.01;

  // 更新 CubeCamera
  sphere.visible = false;    // 隐藏小球自身,防止自我反射
  cubeCamera.position.copy(sphere.position);
  cubeCamera.update(renderer, scene);
  sphere.visible = true;     // 更新后显示小球

  // 渲染场景
  renderer.render(scene, camera);
}

animate();

// 自适应屏幕尺寸变化
window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

✅ 小技巧:在 update 前先让物体不可见,避免它自己反射自己哦!


🔥 小Tips

  • 想让反射更加清晰?可以调高 WebGLCubeRenderTarget 的分辨率,比如从 256 改到 512

  • 如果性能吃紧,可以每隔几帧再调用 cubeCamera.update,比如:

javascript 复制代码
let frameCount = 0;
function animate() {
  requestAnimationFrame(animate);
  box.rotation.y += 0.01;

  frameCount++;
  if (frameCount % 5 === 0) { // 每5帧更新一次反射
    sphere.visible = false;
    cubeCamera.position.copy(sphere.position);
    cubeCamera.update(renderer, scene);
    sphere.visible = true;
  }

  renderer.render(scene, camera);
}

这样可以节省大量性能哦!🚀


🛠️ 常见问题Tips

  1. 为什么我的物体反射是静态的?

    要每帧调用 cubeCamera.update(renderer, scene) 哦!

  2. 为什么会看到物体自己?

    update 前把要反射的物体设为 visible = false,更新后再设回 true

  3. CubeCamera会很耗性能吗?

    是的,它每帧渲染6次场景,比较重。可以根据需要调整更新频率,比如每隔几帧更新一次~🐢


🎯 总结

今天我们详细了解了Three.js中的CubeCamera ,包括它的定义、作用、使用方法和注意事项。

是不是觉得原来制作一个实时反射效果也没那么难?🥳

掌握CubeCamera,你就可以打造更加真实、酷炫的3D世界了!


📚 参考资料

  • Three.js官方文档 - CubeCamera

  • Three.js官方示例 - webgl_materials_cubemap_dynamic


🚀 喜欢的话记得点赞👍收藏🌟支持一下呀!

如果你还有什么想了解的Three.js知识,欢迎留言告诉我!💬

一起进步,一起飞!💪

相关推荐
DianSan_ERP2 小时前
电商架构演进:如何在高并发场景下实现多平台API的标准化履约?
运维·前端·网络·安全·架构·自动化
殳翰2 小时前
下服务器端开发流程及相关工具介绍(C++)
开发语言·c++
落寞的星星2 小时前
这个对象就包含了已经转换好的DFA和各种词法分析器运转所需要的参数。下一步,我们就可以用ScannerInfo对象创建出Scanner对象,请看下面的代码:
开发语言·c#
nothing&nowhere3 小时前
用 Python 做问卷数据清洗:无效样本检测与处理实战
开发语言·python·数据清洗·数据处理·问卷星·问卷星脚本·刷问卷
2601_961593423 小时前
Rust 开发环境配置繁琐?RustRover 开箱即用搞定编码调试
开发语言·后端·macos·rust
HZZD_HZZD4 小时前
DL/T 645-2026新国标深度解读与智能电表协议适配实战:从帧结构变化到Java采集器升级的全链路改造方案
java·开发语言
碎_浪5 小时前
给键盘党的英语记忆工具:我做了一款「打字背单词」桌面应用
前端·程序员·ai编程
阿成学长_Cain6 小时前
Linux dirs命令详解|Bash目录堆栈管理快速切换目录实战教程
linux·运维·前端·数据库
多加点辣也没关系6 小时前
JavaScript|第4章:类型转换
开发语言·javascript
聪慧的水蜜桃6 小时前
【YFIOs】用C#开发硬件之设备上云
开发语言·c#