threejs 学习笔记

threeJS 是一个用于创建 3D 图形的 JavaScript 库。它提供了许多概念和功能,包括:

  • 场景(Scene):threeJS 中所有的 3D 对象都存在于场景中。场景是一个容器,可以添加和删除对象,控制相机和光源等。

  • 相机(Camera):相机定义了场景中可见区域的位置和大小。通过移动和旋转相机,可以改变场景中的视角。

  • 渲染器(Renderer):渲染器将场景和相机中的所有对象渲染成 2D 图像,以显示在屏幕上。

  • 材质(Material):材质定义了 3D 对象的外观,包括颜色、纹理、透明度等。

  • 几何体(Geometry):几何体定义了 3D 对象的形状,包括点、线、面等。

  • 网格(Mesh):网格是几何体和材质的组合,是场景中显示的对象。

  • 光源(Light):光源用于照亮场景中的对象,包括环境光、点光源、聚光灯和方向光等。

  • 控制器(Controller):控制器可以用于交互式地控制相机和场景中的对象,包括鼠标控制器、触摸控制器和 VR 控制器等。

场景 (Scene)

在 Three.js 中,场景(Scene)是所有 3D 对象的容器,包括相机、灯光、物体等。可以通过创建一个场景对象来添加和管理所有的 3D 对象。

以下是创建和使用场景的基本步骤:

  1. 创建场景对象:
var scene = new THREE.Scene();
  1. 添加相机到场景中:
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
scene.add(camera);
  1. 添加渲染器到页面中:
var renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
  1. 创建一个立方体对象,并添加到场景中:
var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
  1. 渲染场景:
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

在上述代码中,我们创建了一个场景对象,并添加了一个透视相机和一个绿色的立方体对象到场景中。然后,我们创建了一个渲染器对象,并将其添加到页面中。最后,我们使用 requestAnimationFrame 函数来循环渲染场景。

通过添加和移除不同的 3D 对象,以及调整相机和灯光等参数,我们可以创建出各种独特的 3D 场景效果。

常用 API

以下是 Three.js 中场景(Scene)对象的一些常用 API:

  • add(object):向场景中添加一个 3D 对象,参数 object 可以是 Mesh、Camera、Light、Group 等 Three.js 中的对象。

  • remove(object):从场景中移除一个 3D 对象,参数 object 必须是已经添加到场景中的对象。

  • getObjectById(id):根据对象的 ID 获取场景中的对象,返回值为该对象,如果不存在则返回 undefined

  • getObjectByName(name):根据对象的名称获取场景中的对象,返回值为该对象,如果不存在则返回 undefined

  • traverse(callback):遍历场景中的所有子对象,并对每个子对象调用指定的回调函数 callback

  • dispose():释放场景中所有子对象及其占用的内存空间。

  • background:设置或获取场景的背景颜色或背景纹理。可以使用颜色值、图片路径或 CubeTexture 对象来设置背景。

  • fog:设置或获取场景的雾效果。可以使用 Fog 或 FogExp2 对象来设置雾效果。

以上是一些常用的场景 API,通过使用这些 API,开发者可以方便地向场景中添加、移除、获取和管理各种 3D 对象,以及设置背景和雾效果等场景属性。

相机

在 Three.js 中,常用的相机类型有透视投影相机(PerspectiveCamera)和正交投影相机(OrthographicCamera)。

透视投影相机用于模拟人眼观察物体时的透视效果,可以让远处的物体看起来比近处的物体更小。创建透视投影相机时需要指定相机的垂直视角(fov)、宽高比(aspect)、近截面(near)和远截面(far)等参数。

正交投影相机则不会产生透视效果,它会将场景中的所有物体等比例缩放到屏幕上,从而保持它们的大小不变。创建正交投影相机时需要指定相机的左、右、上、下边界、近截面和远截面等参数。

除了常用的透视投影相机(PerspectiveCamera)和正交投影相机(OrthographicCamera)之外,还有以下一些特殊的相机类型:

  • CubeCamera:用于创建立方体贴图,可以从不同方向渲染场景,并将渲染结果保存到一个立方体贴图中。

  • ArrayCamera:用于创建多相机视角,可以同时渲染多个视角的场景,并将渲染结果合并到一个屏幕上。

  • StereoCamera:用于创建立体视觉效果,可以同时渲染左右两个视角的场景,并将渲染结果合并到一个屏幕上。

  • PerspectiveCameraWithCubemap:用于创建基于立方体贴图的全景相机,可以将场景渲染到一个立方体贴图中,并使用该贴图作为全景相机的背景。

  • CombinedCamera:用于创建组合相机,可以同时使用透视投影和正交投影两种投影方式,实现更加灵活的视角控制。

相机常用 api

以下是相机常用 API 的详细内容:

  • position:相机的位置,是一个 Vector3 对象,可以通过设置其 x、y、z 坐标来改变相机的位置。例如,可以使用 camera.position.set(0, 0, 10) 将相机设置在场景原点后方 10 个单位处。

  • lookAt(target):设置相机的视点,使其朝向目标点,参数 target 是一个 Vector3 对象,表示相机要朝向的目标点。例如,可以使用 camera.lookAt(new THREE.Vector3(0, 0, 0)) 将相机的视点设置为场景原点。

  • up:相机的上方向,是一个 Vector3 对象,表示相机的上方向。默认情况下,相机的上方向是 y 轴正方向。可以通过设置 camera.up 属性来改变相机的上方向,例如,可以使用 camera.up.set(0, 1, 0) 将相机的上方向设置为 y 轴正方向。

  • near:相机的近截面,即相机到视锥体近端的距离。默认值为 0.1 单位,可以通过设置 camera.near 属性来改变近截面的距离。例如,可以使用 camera.near = 1 将近截面距离设置为 1。

  • far:相机的远截面,即相机到视锥体远端的距离。默认值为 2000 单位,可以通过设置 camera.far 属性来改变远截面的距离。例如,可以使用 camera.far = 5000 将远截面距离设置为 5000。

  • aspect:相机的宽高比,即视锥体的宽度与高度之比。默认值为窗口的宽高比,可以通过设置 camera.aspect 属性来改变宽高比。例如,可以使用 camera.aspect = 16 / 9 将宽高比设置为 16:9。

  • fov:相机的垂直视角,即视锥体的顶面和底面之间的夹角。默认值为 50 度,可以通过设置 camera.fov 属性来改变视角大小。例如,可以使用 camera.fov = 60 将视角大小设置为 60 度。

  • zoom:相机的缩放比例,可以用于调整场景中物体的大小。默认值为 1,表示物体大小不变。可以通过设置 camera.zoom 属性来改变缩放比例。例如,可以使用 camera.zoom = 2 将物体放大两倍。

  • projectionMatrix:相机的投影矩阵,该矩阵用于将场景中的 3D 坐标转换为屏幕上的 2D 坐标。可以通过访问 camera.projectionMatrix 属性来获取相机的投影矩阵。

  • updateProjectionMatrix():更新相机的投影矩阵,当相机参数发生变化时需要调用该方法来更新投影矩阵。例如,当改变相机的宽高比、近截面或远截面时,需要调用 camera.updateProjectionMatrix() 来更新投影矩阵。

  • clone():克隆相机对象,返回一个新的相机对象,可以用于创建多个相同参数的相机。例如,可以使用 var camera2 = camera.clone() 克隆一个和原相机参数相同的新相机对象。

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

// 创建透视相机
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5; // 将相机位置设置为 (0, 0, 5),使其朝向场景中心

// 创建渲染器
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建一个立方体
var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 创建相机控制器
var controls = new THREE.OrbitControls(camera, renderer.domElement);

// 渲染场景
function render() {
    requestAnimationFrame(render);
    // 旋转立方体
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
    // 更新相机控制器
    controls.update();
    renderer.render(scene, camera);
}
render();