导入 three.js
并非所有特性都通过 three 模块导入,controls、loaders 和 post-processing effects 等特性需要从子文件夹 examples/jsm 导入。
创建一个 scene(场景)
为了能使用 three.js 进行展示,我们需要三个东西:scene、camera、renderer,然后就可以“render the scene with camera”。
import { Scene, PerspectiveCamera, WebGLRenderer } from "three";
const scene = new Scene();
const camera = new PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight, false);
document.body.appendChild(renderer.domElement);
three.js 支持的 camera 有很多,PerspectiveCamera(中心投影的 camera)是其中一种。
PerspectiveCamera 有四个参数:fov(field of view, 视场角)/aspect(宽高比)/near(camera 视锥近平面的深度值,近于这一平面的不渲染)/far(camera 视锥远平面的深度值,远于这一平面的不渲染)。
three.js 支持的 renderer 有很多,WebGLRenderer 是其中一种。renderer 实例上的 setSize 方法有三个参数:width(渲染区域的宽度)/height(渲染区域的高度)/updateStyle(是否启用全分辨率),updateStyle 为 false 时,启用半分辨率。
renderer 的 domElement 属性是一个 canvas,用于展示 scene。
const geometry = new BoxGeometry();
const material = new MeshBasicMaterial({ color: 0x00ff00 });
const cube = new Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
一个 Mesh(几何体)的描述分为两部分:geometry(形状)、material(样式)。
BoxGeometry 是 three.js 支持的一种 geometry,用于描述 cube(长方体)这种几何体。包含了 cube 的所有 points(也是 vertices,顶点)和 fills(填充面)。
MeshBasicMaterial 是 three.js 支持的一种 material,它接收一个样式对象,该对象最终将应用到 geometry 上。
Mesh 接收一个 geometry,并应用一个 material 到该 geometry 上面。
Scene 实例上的 add 方法添加的几何体都位于原点。
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
render/animate loop 用于创建动画,在整个 APP 运行中所作的任何变动都应该写到 animate loop 里面。
最终,把 demo 跑起来就可以看到一个旋转的绿色立方体:
画线
const renderer = new WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const camera = new PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
500
);
camera.position.set(0, 0, 100);
camera.lookAt(0, 0, 0);
const scene = new Scene();
position 属性描述 camera 的具体位置。
lookAt 方法将 camera 转向指定方位。
const points = [
new Vector3(-10, 0, 0),
new Vector3(0, 10, 0),
new Vector3(10, 0, 0),
];
const geometry = new BufferGeometry().setFromPoints(points);
const material = new LineBasicMaterial({ color: 0x0000ff });
const line = new Line(geometry, material);
scene.add(line);
scene.background = new Color(0xffffff);
renderer.render(scene, camera);
BufferGeometry 可以描述 mesh/line/point 等 geometry。setFromPoints 方法根据 points 数组为该 BufferGeometry 设置属性。
LineBasicMaterial 是 three.js 支持的一种 material,用于为线框类型的 geometry 添加样式。
Line 接收一个 geometry,并将 material 应用到该 geometry 上面,用于描述连续的多条线段。
把 demo 跑起来就可以看到一个向上的蓝色箭头:
创建文本
-
DOM + CSS
-
CSS2DRenderer/CSS3DRenderer
使用这些 renderer 可以在 scene 中画出包含在 DOM 中的高质量文本。这类似于第一种方式,但这些 renderer 元素更加紧密且动态地集成在了 scene 里面。
- 把文本画到 canvas 中并用作 Texture
这一方法可以方便地在 scene 中的平面上画文本。
- 使用 3D 应用创建一个 model 并导入到 three.js
这一方法适用于那些更喜欢使用其它 3D 应用工作的人。
- TextGeometry
three.js 提供的 TextGeometry 可以在程序中动态创建 3D 文本 geometry。这可以通过创建一个 geometry 为 TextGeometry 实例的 mesh 来实现。为了能够正常工作,TextGeometry 需要一个 Font 实例作为第二个对象类型参数的 font 属性值。
- Bitmap Fonts
BMFonts(bitmap fonts)允许将字形批处理为单个 BufferGeometry。BMFont 渲染支持文字换行、字母间距等。
- Troika Text
troika-three-text 包使用类似 BMFonts 的技术渲染优质的抗锯齿文本,但它可以直接使用 .TTF/.WOFF 文件工作,而无需离线预生成一个 glyph texture。