three.js 示例学习 | 02-挤压缓冲几何体ExtrudeGeometry

1,004 阅读3分钟

前言

上篇简单案例往场景中添加了立方体(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…