本文在前节的基础上,介绍three.js其它的内置几何体。
// 引入Three.js库的全部功能,并将其命名为THREE
import * as THREE from 'three';
// 引入交互控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
// 创建一个场景
const scene = new THREE.Scene();
// 创建一个透视相机,参数分别为视野角度、视口宽高比、近端距离、远端距离
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 创建一个WebGL渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器的大小为窗口的宽度和高度
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染器的canvas元素添加到HTML文档中的body标签中
document.body.appendChild(renderer.domElement);
//------------- 下面放创建几何体的代码 -----------------------
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const myGeometry = new THREE.Mesh(geometry, material);
scene.add(myGeometry);
//--------------- 创建几何体代码结束 --------------------------
// 创建一个平行光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1).normalize(); // 设置光源的方向
scene.add(directionalLight);
const controls = new OrbitControls(camera, renderer.domElement);
camera.position.z = 5;
// 创建一个动画函数
function animate() {
// 请求下一帧动画
requestAnimationFrame(animate);
// 更新 OrbitControls
controls.update();
myGeometry.rotation.x += 0.01;
myGeometry.rotation.y += 0.01;
// 渲染场景
renderer.render(scene, camera);
}
animate()
在上面的示例代码里,注释部分 下面放创建几何体的代码
到 创建几何体代码结束
之间是放后续示例代码的位置。
示例中使用了一个平行光源,关于光源的使用方法在后续章节详细介绍。
胶囊几何体是一种有球形顶端和圆柱形部分组合的几何体。
其构造函数:
THREE.CapsuleGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, cappedTop, cappedBottom, thetaStart, thetaLength)
参数说明:
const geometry = new THREE.CapsuleGeometry( 1, 1, 4, 8 );
const material = new THREE.MeshPhongMaterial( {color: 0x00ff00} );
const myGeometry = new THREE.Mesh( geometry, material ); scene.add( myGeometry );
运行效果:
本示例中使用了一个新的材质 : MeshPhongMaterial,这种材质基于 Phong 反射模型,用于模拟物体表面的光照和阴影。 关于材质的具体使用方式也在后续章节详细介绍。
通过增加 radialSegments 分段数,可以看到球体变得更圆滑:
圆锥体是一种具有尖顶和圆锥底部的几何体。 构造函数如下:
THREE.ConeGeometry(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength)
其参数说明:
const geometry = new THREE.ConeGeometry( 1, 1, 20, 40 );
const material = new THREE.MeshPhongMaterial( {color: 0x00ff00} );
const myGeometry = new THREE.Mesh( geometry, material ); scene.add( myGeometry );
运行效果:
十二面体是一种具有 12 个面的多面体。DodecahedronGeometry
的构造函数的参数如下:
THREE.DodecahedronGeometry(radius, detail)
参数说明:
当detail值非0时,几何体每个面会被分成更多的三角形,以致于detail比较大的时候,展现出来的几何体会像个球体。
const radius = 2;
const detail = 0;
const dodecahedronGeometry = new THREE.DodecahedronGeometry(radius, detail);
const material = new THREE.MeshPhongMaterial({ color: 0x00ff00 });
const myGeometry = new THREE.Mesh(dodecahedronGeometry, material);
scene.add(myGeometry);
运行效果:
修改detail值为5:
EdgesGeometry 通常基于其它几何体,用来生成边缘几何体图形。
其构造函数:
THREE.EdgesGeometry(geometry, thresholdAngle)
参数说明:
const originalGeometry = new THREE.BoxGeometry(3, 3, 3);
const edgesGeometry = new THREE.EdgesGeometry(originalGeometry);
const material = new THREE.LineBasicMaterial({ color: 0xFFFF00 });
const myGeometry = new THREE.LineSegments(edgesGeometry, material);
scene.add(myGeometry);
这里创建了一个立方体,边缘几何体基于立方体来创建,运行效果:
挤出几何体是通过沿着轮廓路径将一个平面形状挤压而成的三维形状。这个类的构造函数接受两个主要参数:轮廓路径和挤出选项。
构造函数:
THREE.ExtrudeGeometry(shapes, options)
参数说明:
const width = 3;
const height = 1;
const depth = 1;
const extrudeAmount = 3;
// 创建一个矩形轮廓
const rectShape = new THREE.Shape();
rectShape.moveTo(0, 0);
rectShape.lineTo(0, height);
rectShape.lineTo(width, height);
rectShape.lineTo(width, 0);
rectShape.lineTo(0, 0);
// 设置挤出选项
const extrudeOptions = {
amount: extrudeAmount,
bevelEnabled: true,
bevelSegments: 2,
steps: 1,
bevelSize: 0.5,
bevelThickness: 0.5,
};
// 创建 ExtrudeGeometry
const geometry = new THREE.ExtrudeGeometry(rectShape, extrudeOptions);
// 创建材质和网格
const material = new THREE.MeshBasicMaterial({ color: 0x00ffFF, wireframe: true });
const myGeometry = new THREE.Mesh(geometry, material);
scene.add(myGeometry);
运行效果:
THREE.IcosahedronGeometry(radius, detail)
参数说明:
const radius = 1;
const detail = 1;
const icosahedronGeometry = new THREE.IcosahedronGeometry(radius, detail);
const material = new THREE.MeshPhongMaterial({ color: 0x00ff00, wireframe: true });
const myGeometry = new THREE.Mesh(icosahedronGeometry, material);
scene.add(myGeometry);
运行效果:
榫卯体又称为旋转体,是通过旋转二维轮廓形状而成的三维几何体。LatheGeometry 的构造函数接受两个主要参数:路径(轮廓)和细分层级。
构造函数:
THREE.LatheGeometry(points, segments, phiStart, phiLength)
参数说明:
// 定义轮廓的点
const points = [];
for (let i = 0; i < 10; i++) {
const x = Math.sin(i) * 2;
const y = (i - 10)*0.5 ;
points.push(new THREE.Vector2(x, y));
}
// 创建线条几何体,这个几体体只是为了方便查看轮廓点的位置
const geometry = new THREE.BufferGeometry().setFromPoints(points);
// 创建线条材质
const material1 = new THREE.LineBasicMaterial({ color: 0x00ff00 });
// 创建线条对象
const line = new THREE.Line(geometry, material1);
scene.add(line);
line.rotation.x = 1;
line.rotation.y = 0;
line.rotation.z = 0;
// 完成线条几何体的创建
// 基于上面的线段创建 LatheGeometry
const latheGeometry = new THREE.LatheGeometry(points, 50);
const material = new THREE.MeshBasicMaterial({ color: 0xFF2222, wireframe: true });
const myGeometry = new THREE.Mesh(latheGeometry, material);
scene.add(myGeometry);
THREE.OctahedronGeometry(radius, detail)
const radius =1;
const detail = 0;
const octahedronGeometry = new THREE.OctahedronGeometry(radius, detail);
const material = new THREE.MeshBasicMaterial({ color: 0x00ffff, wireframe: true });
const myGeometry = new THREE.Mesh(octahedronGeometry, material);
scene.add(myGeometry);
THREE.RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments)
参数说明:
const innerRadius = 1;
const outerRadius = 2;
const thetaSegments = 8;
const phiSegments = 8;
const ringGeometry = new THREE.RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
const myGeometry = new THREE.Mesh(ringGeometry, material);
scene.add(myGeometry);
THREE.TetrahedronGeometry(radius, detail, type)
const radius = 2;
const detail = 0;
const type = 'regular';
const tetrahedronGeometry = new THREE.TetrahedronGeometry(radius, detail, type);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
const myGeometry = new THREE.Mesh(tetrahedronGeometry, material);
scene.add(myGeometry);
THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments)
const radius = 2;
const tube = 1;
const radialSegments = 8;
const tubularSegments = 32;
const torusGeometry = new THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments);
const material = new THREE.MeshBasicMaterial({ color: 0x00ffff, wireframe: true });
const myGeometry = new THREE.Mesh(torusGeometry, material);
scene.add(myGeometry);
THREE.TorusKnotGeometry(radius, tube, tubularSegments, radialSegments, p, q)
const radius = 5;
const tube = 1;
const tubularSegments = 64;
const radialSegments = 8;
const p = 2;
const q = 3;
const torusKnotGeometry = new THREE.TorusKnotGeometry(radius, tube, tubularSegments, radialSegments, p, q);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
const torusKnot = new THREE.Mesh(torusKnotGeometry, material);
scene.add(torusKnot);
TubeGeometry(path,tubularSegments ,radius,radialSegments, closed )
class CustomSinCurve extends THREE.Curve {
constructor( scale = 1 ) {
super();
this.scale = scale;
}
getPoint( t, optionalTarget = new THREE.Vector3() ) {
const tx = t * 3 - 1.5;
const ty = Math.sin( 2 * Math.PI * t );
const tz = 0;
return optionalTarget.set( tx, ty, tz ).multiplyScalar( this.scale );
}
}
const path = new CustomSinCurve( 10 );
const geometry = new THREE.TubeGeometry( path, 20, 2, 8, false );
const material = new THREE.MeshPhongMaterial( { color: 0x00ffff } );
const myGeometry = new THREE.Mesh( geometry, material );
scene.add( myGeometry );
THREE.WireframeGeometry(geometry)
参数 geometry是原始的几何体。
const geometry = new THREE.SphereGeometry( 10, 10, 10 );
const wireframe = new THREE.WireframeGeometry( geometry );
const myGeometry = new THREE.LineSegments( wireframe );
myGeometry.material.depthTest = false;
myGeometry.material.opacity = 0.5;
myGeometry.material.transparent = true;
scene.add( myGeometry );