前言
上篇简单案例往场景中添加了立方体(BoxGeometry),还有圆柱体,球体等,这些形状都是已经固定的。这篇我们将添加挤压缓冲几何体(ExtrudeGeometry),将一个2D形状拉伸成一个几何体。
实现
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
let camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0,0,500);
let scene = new THREE.Scene();
scene.background = new THREE.Color( 0x222222 );
let renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio); // 设置分辨率同步
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 灯光
scene.add(new THREE.AmbientLight(0x222222));
const light = new THREE.PointLight(0xffffff);
light.position.copy(camera.position);
scene.add(light);
// 添加三维辅助坐标系
const axesHelper = new THREE.AxesHelper( 300 );
scene.add( axesHelper );
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
添加基本场景结构
let controls = new OrbitControls(camera, renderer.domElement);
controls.minDistance = 200;
controls.maxDistance = 500;
minDistance和 maxDistance值得是控制器相机能够移动的最小距离和最大距离,这个距离是指和原点的距离,即上面代码中是指相机只能在距离原点200至500的距离内移动。
// 路径线路
const closedSpline = new THREE.CatmullRomCurve3( [
new THREE.Vector3( - 60, - 100, 60 ),
new THREE.Vector3( - 60, 20, 60 ),
new THREE.Vector3( - 60, 120, 60 ),
new THREE.Vector3( 60, 20, - 60 ),
new THREE.Vector3( 60, - 100, - 60 )
], true, 'catmullrom');
CatmullRomCurve3 是通过一系列点创建出一条光滑的三维曲线,构造参数
points – Vector3点数组
closed – 该曲线是否闭合,默认值为false。
curveType – 曲线的类型,默认值为centripetal。
tension – 曲线的张力,默认为0.5。
const pts1 = [],
count = 3;
for ( let i = 0; i < count; i ++ ) {
const l = 20;
const a = 2 * i / count * Math.PI;
pts1.push( new THREE.Vector2( Math.cos( a ) * l, Math.sin( a ) * l ) );
}
const shape = new THREE.Shape( pts1 );
在一个半径为20的圆上均匀的取三个点组成数组,这些点是二维空间的点。将这些点生成定义一个二维形状平面(Shape), 应该是这个样子:
const extrudeOptions= {
steps: 100,
bevelEnabled: false,
extrudePath: closedSpline
};
const geometry1 = new THREE.ExtrudeGeometry( shape, extrudeOptions);
const material1 = new THREE.MeshLambertMaterial( { color: 0xb00000 } );
const mesh1 = new THREE.Mesh( geometry1, material1 );
scene.add( mesh1 );
extrudeOptions参数中
- steps :用于沿着挤出样条的深度细分的点的数量,数字越大,表面越精细光滑。
- bevelEnabled :对挤出的形状应用是否斜角。
- extrudePath:用于挤压shape的三维路径,是对shape 原点位置进行拉伸的。
二维图形 shape 和 extrudeOptions参数生成 ExtrudeGeometry (挤压缓冲几何体),再与材质(MeshLambertMaterial)构成Mesh 添加到场景中。
const pts2 = [], numPts = 5;
for ( let i = 0; i < numPts * 2; i ++ ) {
const l = i % 2 === 1 ? 10 : 20;
const a = i / numPts * Math.PI;
pts2.push( new THREE.Vector2( Math.cos( a ) * l, Math.sin( a ) * l ) );
}
const shape2 = new THREE.Shape( pts2 );
const material2 = new THREE.MeshLambertMaterial( { color: 0xff8000 } );
const materials = [ material1, material2 ];
取十个点连成五角星。
const extrudeSettings3 = {
depth: 20,
steps: 1,
bevelEnabled: true,
bevelThickness: 2,
bevelSize: 4,
bevelSegments: 3
};
const geometry3 = new THREE.ExtrudeGeometry( shape2, extrudeSettings3 );
const mesh3 = new THREE.Mesh( geometry3, materials );
mesh3.position.set( 50, 100, 50 );
scene.add( mesh3 );
- depth :挤出的形状的深度,默认值为1。
- bevelEnabled :对挤出的形状应用是否斜角,默认值为true。
- bevelThickness :设置原始形状上斜角的厚度。默认值为0.2。
- bevelSize :斜角与原始形状轮廓之间的延伸距离。
- bevelSegments :斜角的分段层数。
bevelEnabled 设置切角, 构成 mesh 的 materials为数组,第二个材质即应用到切角上。
bevelThickness表示 a 的宽度,bevelSize表示 b 的宽度,bevelSegments表示 c 的层数
结语
参考官网实例:threejs.org/examples/?q…