[Three.js] 场景、渲染器、相机

profile image

了解在Three.js中展示内容所需的三个最基本元素:场景、渲染器和相机。

本帖由 Jetbrains's Coding Agent Junie junie logo翻译。如有任何翻译错误,请告知我们!

场景、渲染器、相机

让我们了解在Three.js中展示内容所需的三个最基本元素:场景、渲染器和相机。

场景

在使用Three.js实现3D图形时,最基本的元素就是场景(Scene)。场景作为3D世界的容器,是我们想要展示的所有3D对象放置的空间。想象一下电影拍摄现场 - 就像演员、道具和灯光都安排在一个场景中一样,Three.js的场景是所有3D对象放置的空间。

javascript
// 创建场景
const scene = new THREE.Scene();

场景图

场景使用称为场景图(Scene Graph)的树状结构来管理对象。这允许通过父子关系系统地组织对象。

Image.tiff

这个结构中的每个节点代表一个局部空间。此外,子对象继承其父对象的变换(位置、大小、旋转)。

javascript
// 创建父对象
const parent = new THREE.Object3D();
scene.add(parent);

// 创建子对象并添加到父对象
const child = new THREE.Mesh(geometry, material);
parent.add(child);

通过有效利用这些属性,即使是复杂的动画也可以相对容易地计算和实现。以下是一些例子:

  1. 分组

    javascript
    // 不使用场景图,单独管理每个对象
    car.position.x += 10;
    wheel1.position.x += 10;
    wheel2.position.x += 10;
    wheel3.position.x += 10;
    wheel4.position.x += 10;
    
    // 使用场景图
    carGroup.position.x += 10;  // 所有子对象自动一起移动
  2. 相对位置/旋转/缩放

    typescript
    // 设置相对于父对象的位置
    const door = new THREE.Mesh(doorGeometry, doorMaterial);
    door.position.set(1, 0, 0);  // 门位于房子的右侧
    house.add(door);
    
    // 当房子移动时,门自动跟随
    house.position.set(10, 0, 0);
    
    
    // 对于挥动手臂的动画
    // 不使用场景图,需要每次基于肩膀位置计算
    arm.position.x = shoulder.position.x + Math.sin(time) * armLength;
    arm.position.y = shoulder.position.y + Math.cos(time) * armLength;
    
    // 使用场景图,只需简单旋转
    shoulder.add(arm);
    shoulder.rotation.z = Math.sin(time);

相机

在Three.js中,相机决定从哪个视角观察3D场景。像真实的相机一样,你可以调整其位置、方向、视野等属性来表达所需的场景。

透视相机(PerspectiveCamera)

这是一种具有透视效果的相机,类似于人眼或真实相机。PerspectiveCamera基于四个属性创建一个视锥体

Image.png

Image.png

  1. FOV(视野角度)
    • 相机视野的角度(以度为单位)
  2. 宽高比
    • 相机视口的宽/高比例
    • 通常使用浏览器窗口的宽/高比例
    • 也可以设置为4:3、16:9等比例
    • 防止屏幕看起来变形的重要属性
  3. Near(最小距离)
    • 相机可以看到的最小距离
    • 比这个距离更近的对象将不可见
  4. Far(最大距离)
    • 相机可以看到的最大距离
    • 比这个距离更远的对象将不可见

渲染器

渲染器接收场景和相机的信息,并将其转换为我们实际可以在屏幕上看到的图像。例如,可以将其视为将电影制作中的原始胶片开发和处理成观众可以观看的电影的过程。

javascript
const canvas = document.getElementById('canvas') as HTMLCanvasElement
const renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight); // 设置屏幕大小
document.body.appendChild(renderer.domElement); // 添加到HTML

// 为每一帧创建新场景的过程
function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}
animate();

参考

❤️ 0
🔥 0
😎 0
⭐️ 0
🆒 0