three.js基础之Curve、Geometry
为了便于后面的学习封装了几个初始化的函数
import {
WebGLRenderer,
PerspectiveCamera,
AmbientLight,
SpotLight,
PointLight,
DirectionalLight,
PlaneGeometry,
BoxGeometry,
SphereGeometry,
CylinderGeometry,
MeshLambertMaterial,
MeshBasicMaterial,
MeshStandardMaterial,
Mesh,
} from "three";
function initRenderer(domId, width = window.innerWidth, height = window.innerHeight) {
const renderer = new WebGLRenderer({
canvas: document.getElementById(domId),
antialias: true,
});
renderer.setClearColor(0x000000);
renderer.setSize(width, height);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.shadowMap.enabled = true;
return renderer;
}
function initPerspectiveCamera(params = {}) {
const fov = "fov" in params ? params["fov"] : 45;
const aspect = "aspect" in params ? params["aspect"] : window.innerWidth / window.innerHeight;
const near = "near" in params ? params["near"] : 0.1;
const far = "far" in params ? params["far"] : 1000;
const camera = new PerspectiveCamera(fov, aspect, near, far);
camera.position.set(-30, 30, 30);
camera.lookAt(0, 0, 0);
return camera;
}
function initAmbientLight(params = {}) {
const color = "color" in params ? params["color"] : 0xffffff;
const intensity = "intensity" in params ? params["intensity"] : 1;
const ambienLight = new AmbientLight(color, intensity);
return ambienLight;
}
function initSpotLight(params = {}) {
const color = "color" in params ? params["color"] : 0xffffff;
const intensity = "intensity" in params ? params["intensity"] : 20;
const distance = "distance" in params ? params["distance"] : 0;
const angle = "angle" in params ? params["angle"] : Math.PI / 3;
const penumbra = "penumbra" in params ? params["penumbra"] : 0;
const decay = "decay" in params ? params["decay"] : 0.5;
const spotLight = new SpotLight(color, intensity, distance, angle, penumbra, decay);
spotLight.position.set(-30, 30, -30);
spotLight.castShadow = true;
return spotLight;
}
function initPointLight(params = {}) {
const color = "color" in params ? params["color"] : 0xffffff;
const intensity = "intensity" in params ? params["intensity"] : 5;
const distance = "distance" in params ? params["distance"] : 0;
const decay = "decay" in params ? params["decay"] : 0.5;
const pointLight = new PointLight(color, intensity, distance, decay);
pointLight.castShadow = true;
pointLight.position.set(-30, 30, -30);
return ambienLight;
}
function initDirectionalLight(params = {}) {
const color = "color" in params ? params["color"] : 0xffffff;
const intensity = "intensity" in params ? params["intensity"] : 5;
const directionalLight = new DirectionalLight(color, intensity);
directionalLight.position.set(-30, 30, -30);
directionalLight.castShadow = true;
return directionalLight;
}
function addPlane(params = {}) {
const color = "color" in params ? params["color"] : 0xffffff;
const width = "width" in params ? params["width"] : 60;
const height = "height" in params ? params["height"] : 40;
const planeGeometry = new PlaneGeometry(width, height);
const planeMaterial = new MeshLambertMaterial({
color: color,
});
const plane = new Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.rotation.x = -0.5 * Math.PI;
plane.position.set(0, 0, 0);
return plane;
}
function addBox(params = {}) {
const color = "color" in params ? params["color"] : 0xffffff;
const width = "width" in params ? params["width"] : 5;
const height = "height" in params ? params["height"] : 3;
const depth = "depth" in params ? params["depth"] : 2;
const box = new Mesh(
new BoxGeometry(width, height, depth),
new MeshLambertMaterial({
color: color,
})
);
box.position.set(0, 0, 0);
box.castShadow = true;
return box;
}
function addSphere(params = {}) {
const color = "color" in params ? params["color"] : 0xffffff;
const radius = "radius" in params ? params["radius"] : 3;
const sphere = new Mesh(
new SphereGeometry(radius),
new MeshLambertMaterial({
color: color,
})
);
sphere.position.set(0, 0, 0);
sphere.castShadow = true;
return sphere;
}
function addCylinder(params = {}) {
const color = "color" in params ? params["color"] : 0xffffff;
const tRadius = "tr" in params ? params["tr"] : 3;
const bRadius = "br" in params ? params["br"] : 3;
const height = "height" in params ? params["height"] : 10;
const cylinder = new Mesh(
new CylinderGeometry(tRadius, bRadius, height),
new MeshLambertMaterial({
color: color,
})
);
cylinder.castShadow = true;
cylinder.position.set(0, 0, 0);
return cylinder;
}
function addMaterialObjects(scene, gui, controls, meshMaterial) {
const groundGeom = new PlaneGeometry(100, 100, 4, 4);
const groundMesh = new Mesh(
groundGeom,
new MeshBasicMaterial({
color: 0x777777,
})
);
groundMesh.rotation.x = -Math.PI / 2;
groundMesh.position.y = -20;
scene.add(groundMesh);
const sphereGeometry = new SphereGeometry(14, 20, 20);
const cubeGeometry = new BoxGeometry(15, 15, 15);
const planeGeometry = new PlaneGeometry(14, 14, 4, 4);
const sphere = new Mesh(sphereGeometry, meshMaterial);
const cube = new Mesh(cubeGeometry, meshMaterial);
const plane = new Mesh(planeGeometry, meshMaterial);
sphere.position.set(0, 3, 2);
cube.position.copy(sphere.position);
plane.position.copy(sphere.position);
scene.add(cube);
controls.select = cube;
gui.add(controls, "selectedMesh", ["cube", "sphere", "plane"]).onChange(function (e) {
scene.remove(plane);
scene.remove(cube);
scene.remove(sphere);
switch (e) {
case "cube":
scene.add(cube);
controls.select = cube;
break;
case "sphere":
scene.add(sphere);
controls.select = sphere;
break;
case "plane":
scene.add(plane);
controls.select = plane;
break;
}
});
}
export {
initRenderer,
initPerspectiveCamera,
initAmbientLight,
initSpotLight,
initPointLight,
initDirectionalLight,
addPlane,
addBox,
addSphere,
addCylinder,
addMaterialObjects,
};
Curve、Shape、BufferGeometry
共用的初始化方法
<canvas id="EllipseCurve"></canvas>
<canvas id="ArcCurve"></canvas>
<canvas id="CurvePath"></canvas>
<canvas id="SplineCurve-CatmullRomCurve3"></canvas>
<canvas id="QuadraticBezierCurve-CubicBezierCurve"></canvas>
<canvas id="QuadraticBezierCurve3-CubicBezierCurve3"></canvas>
<canvas id="Shape"></canvas>
<canvas id="BufferGeometry"></canvas>
<canvas id="EdgesGeometry"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/addons/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";import { initRenderer, initPerspectiveCamera, initAmbientLight } from "./init.js";
function init(domId, callback) {
const width = 300;
const height = 200;
const renderer = initRenderer(domId, width, height);
const scene = new THREE.Scene();
const camera = initPerspectiveCamera({ aspect: width / height });
scene.add(camera);
const ambientLight = initAmbientLight();
scene.add(ambientLight);
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
callback(scene);
renderer.render(scene, camera);
}
</script>
EllipseCurve
init("EllipseCurve", (scene) => {
// 椭圆曲线, 参数:椭圆的中心的X坐标、椭圆的中心的Y坐标、X轴向上椭圆的半径、Y轴向上椭圆的半径、以弧度来表示从正X轴算起曲线开始的角度、
// 以弧度来表示从正X轴算起曲线终止的角度、椭圆是否按照顺时针方向来绘制
const ellipse = new THREE.EllipseCurve(0, 0, 5, 3, 0, 2 * Math.PI, false);
const pointsArr = ellipse.getPoints(20); //分段数20,返回21个顶点
const pointsArr2 = ellipse.getSpacedPoints(20); //按照曲线长度等间距返回顶点数据
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr); //读取坐标数据赋值给几何体顶点
const geometry2 = new THREE.BufferGeometry();
geometry2.setFromPoints(pointsArr2);
const lineMaterial = new THREE.LineBasicMaterial({
color: 0xffffff,
});
const line = new THREE.Line(geometry, lineMaterial); // 线模型
line.position.set(0, -5, 0);
const line2 = new THREE.Line(geometry2, lineMaterial);
line2.position.set(0, 5, 0);
scene.add(line);
scene.add(line2);
const pointsMaterial = new THREE.PointsMaterial({
color: 0xffffff,
size: 1,
});
const points = new THREE.Points(geometry, pointsMaterial); // 点模型
const points2 = new THREE.Points(geometry2, pointsMaterial);
points.position.set(15, -5, 0);
points2.position.set(15, 5, 0);
scene.add(points);
scene.add(points2);
});
ArcCurve
init("ArcCurve", (scene) => {
// 弧线, 参数:弧线的中心的X坐标、弧线的中心的Y坐标、弧线的半径、以弧度来表示从正X轴算起曲线开始的角度、
// 以弧度来表示从正X轴算起曲线终止的角度、弧线是否按照顺时针方向来绘制
const arc = new THREE.ArcCurve(0, 0, 5, 0, 1.5 * Math.PI, false);
const pointsArr = arc.getPoints(10);
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);
const material = new THREE.LineBasicMaterial({
color: 0xffffff,
});
const line = new THREE.Line(geometry, material);
scene.add(line);
});
CurvePath
init("CurvePath", (scene) => {
const R = 2;
const H = 10;
const line1 = new THREE.LineCurve(new THREE.Vector2(R, H), new THREE.Vector2(R, 0));
const arc = new THREE.ArcCurve(0, 0, R, 0, Math.PI, true);
const line2 = new THREE.LineCurve(new THREE.Vector2(-R, 0), new THREE.Vector2(-R, H));
//组合曲线
const curvePath = new THREE.CurvePath();
curvePath.curves.push(line1, arc, line2);
const pointsArr = curvePath.getPoints(20);
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);
const material = new THREE.LineBasicMaterial({
color: 0xffffff,
});
const line = new THREE.Line(geometry, material);
line.position.set(0, 0, 0);
scene.add(line);
});
SplineCurve、CatmullRomCurve3
init("SplineCurve-CatmullRomCurve3", (scene) => {
const arr_2 = [new THREE.Vector2(-5, 0), new THREE.Vector2(0, 3), new THREE.Vector2(5, 0)];
// 二维样条曲线,从一系列的点中创建一个平滑的二维样条曲线
const curve_2 = new THREE.SplineCurve(arr_2);
const pointsArr_2 = curve_2.getPoints(20);
const geometry_2 = new THREE.BufferGeometry();
geometry_2.setFromPoints(pointsArr_2);
const material = new THREE.LineBasicMaterial({
color: 0x99ffff,
});
const line_2 = new THREE.Line(geometry_2, material);
line_2.position.set(0, 5, 0);
scene.add(line_2);
const arr_3 = [new THREE.Vector3(-5, 0, 0), new THREE.Vector3(0, 3, 0), new THREE.Vector3(5, 0, 0), new THREE.Vector3(0, 0, 8), new THREE.Vector3(0, 0, 0)];
// 三维样条曲线,从一系列的点创建一条平滑的三维样条曲线。
const curve_3 = new THREE.CatmullRomCurve3(arr_3);
const pointsArr_3 = curve_3.getPoints(20);
const geometry_3 = new THREE.BufferGeometry();
geometry_3.setFromPoints(pointsArr_3);
const line_3 = new THREE.Line(geometry_3, material);
line_3.position.set(0, -5, 0);
scene.add(line_3);
});
QuadraticBezierCurve、CubicBezierCurve
init("QuadraticBezierCurve-CubicBezierCurve", (scene) => {
const p1 = new THREE.Vector2(-5, 0);
const p2 = new THREE.Vector2(-2, 5);
const p3 = new THREE.Vector2(2, 3);
const p4 = new THREE.Vector2(5, 0);
// 二维二次贝赛尔曲线, 由起点、终点和一个控制点所定义
const curve_2 = new THREE.QuadraticBezierCurve(p1, p2, p4);
const pointsArr_2 = curve_2.getPoints(50);
const geometry_2 = new THREE.BufferGeometry();
geometry_2.setFromPoints(pointsArr_2);
const material = new THREE.LineBasicMaterial({
color: 0x22ff00,
});
const line_2 = new THREE.Line(geometry_2, material);
line_2.position.set(0, 5, 0);
scene.add(line_2);
// 二维三次贝赛尔曲线,由起点、终点和两个控制点所定义
const curve_3 = new THREE.CubicBezierCurve(p1, p2, p3, p4);
const pointsArr_3 = curve_3.getPoints(50);
const geometry_3 = new THREE.BufferGeometry();
geometry_3.setFromPoints(pointsArr_3);
const material1 = new THREE.LineBasicMaterial({
color: 0xffff00,
});
const line_3 = new THREE.Line(geometry_3, material1);
line_3.position.set(0, -5, 0);
scene.add(line_3);
});
QuadraticBezierCurve3、CubicBezierCurve3
init("QuadraticBezierCurve3-CubicBezierCurve3", (scene) => {
const p1 = new THREE.Vector3(-8, 0, 0);
const p2 = new THREE.Vector3(-4, 5, 0);
const p3 = new THREE.Vector3(5, 5, 0);
const p4 = new THREE.Vector3(8, 0, 5);
// 三维二次贝赛尔曲线, 由起点、终点和一个控制点所定义
const curve_2 = new THREE.QuadraticBezierCurve3(p1, p2, p4);
const pointsArr_2 = curve_2.getPoints(50);
const geometry_2 = new THREE.BufferGeometry();
geometry_2.setFromPoints(pointsArr_2);
const material = new THREE.LineBasicMaterial({
color: 0x22ffff,
});
const line_2 = new THREE.Line(geometry_2, material);
line_2.position.set(0, 5, 0);
scene.add(line_2);
// 三维三次贝赛尔曲线,由起点、终点和两个控制点所定义
const curve_3 = new THREE.CubicBezierCurve3(p1, p2, p3, p4);
const pointsArr_3 = curve_3.getPoints(50);
const geometry_3 = new THREE.BufferGeometry();
geometry_3.setFromPoints(pointsArr_3);
const line_3 = new THREE.Line(geometry_3, material);
line_3.position.set(0, -5, 0);
scene.add(line_3);
});
Shape
init("Shape", (scene) => {
// 平面多边形轮廓
const shape = new THREE.Shape([new THREE.Vector2(-2, -2), new THREE.Vector2(-2, 2), new THREE.Vector2(2, 2), new THREE.Vector2(2, -2)]);
const geometry = new THREE.ShapeGeometry(shape);
const material = new THREE.MeshBasicMaterial({
color: 0xffffff,
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// 平面轮廓 arc
const shape1 = new THREE.Shape();
shape1.moveTo(0, 0);
shape1.lineTo(3, 0); // 绘制直线线段
shape1.arc(0, 0, 5, 0, Math.PI / 2); //圆心坐标是相对于当前currentPoint,而不是坐标原点
shape1.lineTo(0, 5);
const geometry1 = new THREE.ShapeGeometry(shape1);
const material1 = new THREE.MeshBasicMaterial({
color: 0xff0000,
side: THREE.DoubleSide,
});
const mesh1 = new THREE.Mesh(geometry1, material1);
mesh1.position.set(0, 10, 0);
scene.add(mesh1);
// 平面轮廓 absarc
const shape2 = new THREE.Shape();
shape1.moveTo(0, 0);
shape2.lineTo(10, 0);
shape2.absarc(10, 0, 5, 0, Math.PI / 2); // absarc圆心坐标不受到currentPoint影响,以坐标原点作为参考
shape2.lineTo(0, 5);
const path2_1 = new THREE.Path(); // 圆孔
path2_1.absarc(2.5, 2.5, 2);
const path2_2 = new THREE.Path(); // 圆孔
path2_2.absarc(8, 2.5, 2);
shape2.holes.push(path2_1, path2_2); //内孔轮廓分别放入holes属性中
const geometry2 = new THREE.ShapeGeometry(shape2);
const material2 = new THREE.MeshBasicMaterial({
color: 0x0000ff,
side: THREE.DoubleSide,
});
const mesh2 = new THREE.Mesh(geometry2, material2);
mesh2.position.set(0, -10, 0);
scene.add(mesh2);
});
BufferGeometry
init("BufferGeometry", (scene) => {
const material = new THREE.LineBasicMaterial({
color: 0xffffff,
});
const geometry1 = new THREE.BufferGeometry();
const R = 2;
const N = 5;
const sp = (2 * Math.PI) / N;
const arr = [];
const cx = 2;
const cy = 2;
for (let i = 0; i < N; i++) {
const angle = sp * i;
const x = cx + R * Math.cos(angle);
const y = cy + R * Math.sin(angle);
arr.push(x, 0, y);
}
const vertices1 = new Float32Array(arr);
const attribue1 = new THREE.BufferAttribute(vertices1, 3);
geometry1.attributes.position = attribue1;
const line1 = new THREE.LineLoop(geometry1, material);
scene.add(line1);
const geometry2 = new THREE.BufferGeometry();
// 三维向量表示的坐标值
const pointsArr2 = [new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 3, 0), new THREE.Vector3(0, 3, 3), new THREE.Vector3(0, 0, 3)];
geometry2.setFromPoints(pointsArr2);
const line2 = new THREE.LineLoop(geometry2, material);
scene.add(line2);
const geometry3 = new THREE.BufferGeometry();
// 二维向量表示的坐标值
const pointsArr3 = [new THREE.Vector2(0, 0), new THREE.Vector2(5, 0), new THREE.Vector2(5, 5), new THREE.Vector2(0, 5)];
geometry3.setFromPoints(pointsArr3);
const line3 = new THREE.LineLoop(geometry3, material);
scene.add(line3);
});
EdgesGeometry
init("EdgesGeometry", (scene) => {
// 平面轮廓 absarc
const shape = new THREE.Shape();
shape.lineTo(10, 0);
shape.absarc(10, 0, 5, 0, Math.PI / 2);
shape.lineTo(0, 5);
const path1 = new THREE.Path(); // 圆孔
path1.absarc(2, 2, 2);
const path2 = new THREE.Path(); // 圆孔
path2.absarc(8, 2, 2);
shape.holes.push(path1, path2); //内孔轮廓分别放入holes属性中
const geometry = new THREE.ExtrudeGeometry(shape, {
depth: 2, //拉伸长度
bevelEnabled: false, //禁止倒角
curveSegments: 50,
});
const material = new THREE.MeshBasicMaterial({
color: 0xffffff,
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(geometry, material);
// 模型边界线EdgesGeometry
const edges = new THREE.EdgesGeometry(geometry);
const edgesMaterial = new THREE.LineBasicMaterial({
color: 0x00ffff,
});
const line = new THREE.LineSegments(edges, edgesMaterial);
mesh.add(line);
scene.add(mesh);
});
Geometry
<canvas id="geometry"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/addons/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { TrackballControls } from "three/addons/controls/TrackballControls.js";
import { createMultiMaterialObject } from "three/addons/utils/SceneUtils.js";
import { ConvexGeometry } from "three/addons/geometries/ConvexGeometry.js";
import { ParametricGeometry } from "three/addons/geometries/ParametricGeometry.js";
import { ParametricGeometries } from "three/addons/geometries/ParametricGeometries.js";
import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight, addPlane } from "./init.js";
function init() {
const renderer = initRenderer("geometry");
const scene = new THREE.Scene();
const camera = initPerspectiveCamera();
scene.add(camera);
const ambientLight = initAmbientLight();
scene.add(ambientLight);
const spotLight = initSpotLight();
scene.add(spotLight);
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
const plane = addPlane({ width: 100, height: 80 });
plane.position.set(10, 0, 10);
scene.add(plane);
addGeometries(scene);
const trackballControls = new TrackballControls(camera, renderer.domElement);
const clock = new THREE.Clock();
render();
function render() {
trackballControls.update(clock.getDelta());
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function addGeometries(scene) {
const geoms = [];
//平面缓冲几何体,参数:平面沿着 X 轴的宽度,平面沿着 Y 轴的高度
const planeGeometry = new THREE.PlaneGeometry(5, 3);
planeGeometry.rotateX(-Math.PI / 2);
geoms.push(planeGeometry);
//圆形缓冲几何体,参数:圆形的半径
const circleGeometry = new THREE.CircleGeometry(3);
circleGeometry.rotateX(-Math.PI / 2);
geoms.push(circleGeometry);
// 形状缓冲几何体
const pointsArr = [new THREE.Vector2(0, 0), new THREE.Vector2(3, 0), new THREE.Vector2(1, 2)];
const shape = new THREE.Shape(pointsArr);
geoms.push(new THREE.ShapeGeometry(shape));
// 立方缓冲几何体,参数:X 轴上面的宽度、Y 轴上面的高度、Z 轴上面的深度
geoms.push(new THREE.BoxGeometry(2, 2, 2));
// 八面缓冲几何体,参数:八面体的半径
geoms.push(new THREE.OctahedronGeometry(3));
// 二十面缓冲几何体,参数:二十面体的半径
geoms.push(new THREE.IcosahedronGeometry(3));
// 四面缓冲几何体,参数:四面体的半径
geoms.push(new THREE.TetrahedronGeometry(3));
// 圆锥缓冲几何体,参数: 圆锥底部的半径、圆锥的高度
geoms.push(new THREE.ConeGeometry(3, 2));
// 球缓冲几何体,参数:球体半径
geoms.push(new THREE.SphereGeometry(2));
// 圆环缓冲几何体,参数:环面的半径(从环面的中心到管道横截面的中心)、管道的半径、管道横截面的分段数、管道的分段数
geoms.push(new THREE.TorusGeometry(3, 1, 10, 10));
// 圆环缓冲扭结几何体,参数:圆环的半径、管道的半径、管道的分段数量、横截面分段数量
geoms.push(new THREE.TorusKnotGeometry(3, 0.5, 50, 20));
// 圆柱缓冲几何体,参数:圆柱的顶部半径、圆柱的底部半径、圆柱的高度
geoms.push(new THREE.CylinderGeometry(1, 4, 4));
//胶囊缓冲几何体,参数:胶囊半径、中间区域的长度
geoms.push(new THREE.CapsuleGeometry(1, 2));
const pts = [];
const detail = 0.1;
const radius = 3;
for (let angle = 0.0; angle < Math.PI; angle += detail) {
pts.push(new THREE.Vector3(Math.cos(angle) * radius, 0, Math.sin(angle) * radius));
}
// 车削缓冲几何体
geoms.push(new THREE.LatheGeometry(pts, 10));
const p1 = new THREE.Vector3(0, 0, 2);
const p2 = new THREE.Vector3(0, 0, 1);
const p3 = new THREE.Vector3(0, 0, 0);
const p4 = new THREE.Vector3(1, 0, 0);
const p5 = new THREE.Vector3(2, 0, 0);
const line1 = new THREE.LineCurve3(p1, p2);
const curve = new THREE.QuadraticBezierCurve3(p2, p3, p4);
const line2 = new THREE.LineCurve3(p4, p5);
const curvePath = new THREE.CurvePath();
curvePath.curves.push(line1, curve, line2);
//管道几何体,参数:路径、沿着轨迹细分数、管道半径、管道截面圆细分数
geoms.push(new THREE.TubeGeometry(curvePath, 3, 1, 5));
const pointsArr1 = [new THREE.Vector2(-5, -5), new THREE.Vector2(-5, 5), new THREE.Vector2(5, 5), new THREE.Vector2(5, -5)];
const shape1 = new THREE.Shape(pointsArr1);
// 挤压缓冲几何体,参数:形状、参数对象
geoms.push(new THREE.ExtrudeGeometry(shape1, { depth: 2 }));
const shape2 = new THREE.Shape([new THREE.Vector2(0, 0), new THREE.Vector2(0, 3), new THREE.Vector2(3, 3), new THREE.Vector2(3, 0)]);
const curve2 = new THREE.CatmullRomCurve3([new THREE.Vector3(-1, -2, -1), new THREE.Vector3(3, 0, 0), new THREE.Vector3(1, 4, 4), new THREE.Vector3(-2, 0, 5)]);
// 挤压缓冲几何体
const geometry = new THREE.ExtrudeGeometry(shape2, {
extrudePath: curve2,
steps: 100,
});
geoms.push(geometry);
const points = [
new THREE.Vector3(2, 2, 2),
new THREE.Vector3(2, 2, -2),
new THREE.Vector3(-2, 2, -2),
new THREE.Vector3(-2, 2, 2),
new THREE.Vector3(2, -2, 2),
new THREE.Vector3(2, -2, -2),
new THREE.Vector3(-2, -2, -2),
new THREE.Vector3(-2, -2, 2),
];
// 凸包几何体,可被用于为传入的一组点生成凸包
geoms.push(new ConvexGeometry(points));
// 参数化缓冲几何体,生成由参数表示其表面的几何体。
geoms.push(new ParametricGeometry(ParametricGeometries.mobius3d, 20, 10));
let j = 0;
for (let i = 0; i < geoms.length; i++) {
const materials = [
new THREE.MeshLambertMaterial({
color: Math.random() * 0xffffff,
}),
new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true,
}),
];
//多种材质
const mesh = createMultiMaterialObject(geoms[i], materials);
mesh.traverse(function (e) {
e.castShadow = true;
});
mesh.position.x = -24 + (i % 4) * 12;
mesh.position.y = 4;
mesh.position.z = -8 + j * 12;
if ((i + 1) % 4 == 0) j++;
scene.add(mesh);
}
}
}
init();
</script>
合集:
three.js基础
分类:
javascript
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战