06-three.js 创建自己的缓冲几何体
Three.js Journey — Learn WebGL with Three.jsThe ultimate Three.js course whether you are a beginner or a more advanced developerhttps://threejs-journey.com/?c=p3
关键点:
1. new Float32Array()
2. new THREE.BufferAttribute()
3. geometry.setAttribute()
BoxGeometry
BoxGeometry 有 6 个参数:
-
width
:x
轴上的大小 -
height
:y
轴上的大小 -
depth
:z
轴上的大小 -
widthSegments
:x
轴上的细分数量 -
heightSegments
: 在y
轴上的细分数量 -
depthSegments
: 在z
轴上的细分数量
细分对应于面由多少个三角形组成。默认情况下,它为 1
,意味着每个面只有 2 个三角形。如果你将细分设置为 2
,每个面将会有 8 个三角形:
const geometry = new THREE.BoxGeometry(1, 1, 1, 2, 2, 2)
// 向 material 中添加 wireframe: true,线框将显示界定每个三角形的线条
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
const geometry = new THREE.SphereGeometry(1, 32, 32)
创建自己的缓冲几何体
首先实例化一个空的 BufferGeometry。
// 自定义缓冲几何体
// 1. 创建一个空的 BufferGeometry
const geometry = new THREE.BufferGeometry()// 2. 使用 Float32Array 添加几何体顶点
// 首先指定第一个顶点的 x、y 和 z,然后是第二个顶点的 x、y 和 z,依此类推// 方式一
// 创建一个 Float32Array 指定它的长度(比如 9),然后填充它
// const positionArray = new Float32Array(9)// // First vertice
// positionArray[0] = 0
// positionArray[1] = 0
// positionArray[2] = 0// // Second vertice
// positionArray[3] = 0
// positionArray[4] = 1
// positionArray[5] = 0// // Third vertice
// positionArray[6] = 1
// positionArray[7] = 0
// positionArray[8] = 0// 方式二
const positionArray = new Float32Array([0,0,0, // First vertice0,1,0, // Second vertice1,0,0 // Third vertice
])// 将其转换为 BufferAttribute,再发送给 BufferGeometry
const positionAttribute = new THREE.BufferAttribute(positionArray, 3)// 通过使用 setAttribute(...) 方法将这个属性添加到我们的 BufferGeometry ,创建position这个名词的属性
geometry.setAttribute('position', positionAttribute)// 向 material 中添加 wireframe: true,线框将显示界定每个三角形的线条
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
创建一堆随机三角形:
// 1. 创建一个空的 BufferGeometry
const geometry = new THREE.BufferGeometry()
// 随机50个三角形(50*9,需要450个顶点)
// 9代表3个顶点位置,也就是3组 x y z
const count = 50
const positionArray = new Float32Array(count * 3 * 3)
for (let i = 0; i < count * 3 * 3; i++) {positionArray[i] = (Math.random() - 0.5) * 4 // 值在 -2 到接近 2 之间
}// 将其转换为 BufferAttribute,再发送给 BufferGeometry
const positionAttribute = new THREE.BufferAttribute(positionArray, 3)// 通过使用 setAttribute(...) 方法将这个属性添加到我们的 BufferGeometry ,创建position这个名词的属性
geometry.setAttribute('position', positionAttribute)// 向 material 中添加 wireframe: true,线框将显示界定每个三角形的线条
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
【完整代码】
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'// Canvas
const canvas = document.querySelector('canvas.webgl')// Scene
const scene = new THREE.Scene()/*** Object*/
// width: x 轴上的大小
// height: y 轴上的大小
// depth: z 轴上的大小
// widthSegments: x 轴上的细分数量
// heightSegments: 在 y 轴上的细分数量
// depthSegments: 在 z 轴上的细分数量
// const geometry = new THREE.BoxGeometry(1, 1, 1)
// const geometry = new THREE.BoxGeometry(1, 1, 1, 2, 2, 2)
// const geometry = new THREE.SphereGeometry(1, 32, 32)// 自定义缓冲几何体
// 1. 创建一个空的 BufferGeometry
const geometry = new THREE.BufferGeometry()// 2. 使用 Float32Array 添加几何体顶点
// 首先指定第一个顶点的 x、y 和 z,然后是第二个顶点的 x、y 和 z,依此类推// 方式一
// 创建一个 Float32Array 指定它的长度(比如 9),然后填充它
// const positionArray = new Float32Array(9)// // First vertice
// positionArray[0] = 0
// positionArray[1] = 0
// positionArray[2] = 0// // Second vertice
// positionArray[3] = 0
// positionArray[4] = 1
// positionArray[5] = 0// // Third vertice
// positionArray[6] = 1
// positionArray[7] = 0
// positionArray[8] = 0// // 方式二
// const positionArray = new Float32Array([
// 0,0,0, // First vertice
// 0,1,0, // Second vertice
// 1,0,0 // Third vertice
// ])// 随机50个三角形(50*9,需要450个顶点)
// 9代表3个顶点位置,也就是3组 x y z
const count = 50
const positionArray = new Float32Array(count * 3 * 3)
for (let i = 0; i < count * 3 * 3; i++) {positionArray[i] = (Math.random() - 0.5) * 4 // 值在 -2 到接近 2 之间
}// 将其转换为 BufferAttribute,再发送给 BufferGeometry
const positionAttribute = new THREE.BufferAttribute(positionArray, 3)// 通过使用 setAttribute(...) 方法将这个属性添加到我们的 BufferGeometry ,创建position这个名词的属性
geometry.setAttribute('position', positionAttribute)// 向 material 中添加 wireframe: true,线框将显示界定每个三角形的线条
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)/*** Sizes*/
const sizes = {width: window.innerWidth,height: window.innerHeight
}/*** Camera*/// 自定义控制
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 1, 1000)
camera.position.z = 3
camera.lookAt(mesh.position)
scene.add(camera)/*** Controls*/
const controls = new OrbitControls(camera, canvas)
controls.enableDamping = true/*** Renderer*/
const renderer = new THREE.WebGLRenderer({canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
renderer.render(scene, camera)const tick = () => {// Update controlscontrols.update()renderer.render(scene, camera)window.requestAnimationFrame(tick)
}
tick()window.addEventListener('resize', () => {// 1. 更新 sizessizes.width = window.innerWidthsizes.height = window.innerHeight// 2.1 更新 camera aspect 纵横比camera.aspect = sizes.width / sizes.height// 2.2 更新 aspect 时要配合更新投影矩阵 updateProjectionMatrixcamera.updateProjectionMatrix()// 3. 更新 rendererrenderer.setSize(sizes.width, sizes.height)renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))})window.addEventListener('dblclick', () => {if (!document.fullscreenElement) {canvas.requestFullscreen();} else {document.exitFullscreen();}
})
项目创建参考
01-three.js vite基础示例_three.js示例-CSDN博客文章浏览阅读386次。three.js 基本示例代码_three.js示例https://blog.csdn.net/gaowxx/article/details/147954918?spm=1001.2014.3001.5501