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知识,欢迎留言告诉我!💬

一起进步,一起飞!💪

相关推荐
程序员JerrySUN2 小时前
驱动开发硬核特训 · Day 22(下篇): # 深入理解 Power-domain 框架:概念、功能与完整代码剖析
linux·开发语言·驱动开发·嵌入式硬件
萌萌哒草头将军2 小时前
⚡⚡⚡尤雨溪宣布开发 Vite Devtools,这两个很哇塞 🚀 Vite 的插件,你一定要知道!
前端·vue.js·vite
游离状态的猫12 小时前
JavaScript性能优化实战:从瓶颈定位到极致提速
开发语言·javascript·性能优化
GeekABC2 小时前
FastAPI系列06:FastAPI响应(Response)
开发语言·python·fastapi·web
why1513 小时前
腾讯(QQ浏览器)后端开发
开发语言·后端·golang
charade3123 小时前
【C语言】内存分配的理解
c语言·开发语言·c++
浪裡遊3 小时前
跨域问题(Cross-Origin Problem)
linux·前端·vue.js·后端·https·sprint
滿3 小时前
Vue3 Element Plus el-tabs数据刷新方法
javascript·vue.js·elementui
LinDaiuuj3 小时前
判断符号??,?. ,! ,!! ,|| ,&&,?: 意思以及举例
开发语言·前端·javascript