// 创建一个BufferGeometry几何体实例 const geometry = new THREE.BufferGeometry() // 三个一组,为一个顶点坐标(图形是由N个三角形组成) const vertices = new Float32Array([ -100, -100, 100, 100, -100, 100, 100, 100, 100, 100, 100, 100, -100, 100, 100, -100, -100, 100 ]); // 设置几何体的钉钉位置 // 3 表示3个值为一组 geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
完整点的代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=100"> <title>Document</title> </head> <body> <script type="importmap"> { "imports": { "three": "./three.module.min.js", "three/addons/": "./jsm/" } } </script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js' // 创建场景 const scene = new THREE.Scene(); // 创建一个BufferGeometry几何体实例 const geometry = new THREE.BufferGeometry() // 三个一组,为一个顶点坐标(图形是由N个三角形组成) const vertices = new Float32Array([ -100.0, -100, 100, 100, -100, 100, 100, 100, 100, 100, 100, 100, -100, 100, 100, -100, -100, 100 ]); // 设置几何体的钉钉位置 geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3)); // 创建一个基础网格材质(双面可见) const material = new THREE.MeshBasicMaterial({ color: 'orange', side: THREE.DoubleSide }); const cube = new THREE.Mesh(geometry, material); // 将物体加到场景中 scene.add(cube); // 创建 三维坐标轴 const axesHelper = new THREE.AxesHelper(200); scene.add(axesHelper); // 创建相机 let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(300, 300, 300) camera.lookAt(0, 0, 0) const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); // 执行渲染 renderer.render(scene, camera); document.body.appendChild(renderer.domElement); // 创建轨道控制器对象 const controls = new OrbitControls(camera, renderer.domElement) controls.addEventListener('change', function () { // 重新执行渲染操作 renderer.render(scene, camera); }); </script> </body> </html>
我们前面设置定点坐标的时候,用的值是这样的:
const vertices = new Float32Array([
-100, -100, 100, // 第0组
100, -100, 100, // 第1组
100, 100, 100, // 第2组
100, 100, 100, // 第3组
-100, 100, 100, // 第4组
-100, -100, 100 // 第5组
]);
这里面的坐标点数据有些是重复的,比如:第0组和第5组重复,第2组和第3组重复。如果我们将重复的点删除,可以吗?就像这样:
const vertices = new Float32Array([
-100, -100, 100, // 第0组
100, -100, 100, // 第1组
100, 100, 100, // 第2组
-100, 100, 100, // 第3组
]);
其实是可以的,不过这样删除后,还需要设置定点分组,才能获得同样的效果。
const indexes = new Uint16Array([0, 1, 2, 2, 3, 0])
geometry.setIndex(new THREE.BufferAttribute(indexes, 1));
完整的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=100">
<title>Document</title>
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "./three.module.min.js",
"three/addons/": "./jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 创建场景
const scene = new THREE.Scene();
// 创建一个BufferGeometry几何体实例
const geometry = new THREE.BufferGeometry()
// 三个一组,为一个顶点坐标(图形是由N个三角形组成)
const vertices = new Float32Array([
-100, -100, 100, // 第0组
100, -100, 100, // 第1组
100, 100, 100, // 第2组
-100, 100, 100, // 第3组
]);
// 设置几何体的顶点位置
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
// 创建定点索引
const indexes = new Uint16Array([0, 1, 2, 2, 3, 0])
// 设置索引属性
geometry.setIndex(new THREE.BufferAttribute(indexes, 1));
// 创建一个基础网格材质(双面可见)
const material = new THREE.MeshBasicMaterial({ color: 'orange', side: THREE.DoubleSide });
const cube = new THREE.Mesh(geometry, material);
// 将物体加到场景中
scene.add(cube);
// 创建 三维坐标轴
const axesHelper = new THREE.AxesHelper(200);
scene.add(axesHelper);
// 创建相机
let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(300, 300, 300)
camera.lookAt(0, 0, 0)
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
// 执行渲染
renderer.render(scene, camera);
document.body.appendChild(renderer.domElement);
// 创建轨道控制器对象
const controls = new OrbitControls(camera, renderer.domElement)
controls.addEventListener('change', function () {
// 重新执行渲染操作
renderer.render(scene, camera);
})
</script>
</body>
</html>
本节参考文章:
https://threejs.org/docs/?q=Geometry#api/zh/core/BufferGeometry
https://juejin.cn/post/7231080269501956155