06-three.js 创建自己的缓冲几何体

发布于:2025-06-30 ⋅ 阅读:(23) ⋅ 点赞:(0)

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 个参数:

  • widthx 轴上的大小

  • heighty 轴上的大小

  • depthz 轴上的大小

  • widthSegmentsx 轴上的细分数量

  • 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 vertice
    0,1,0, // Second vertice
    1,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 controls
    controls.update()

    renderer.render(scene, camera)
    window.requestAnimationFrame(tick)
}
tick()

window.addEventListener('resize', () => {
    // 1. 更新 sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // 2.1 更新 camera aspect 纵横比
    camera.aspect = sizes.width / sizes.height

    // 2.2 更新 aspect 时要配合更新投影矩阵 updateProjectionMatrix
    camera.updateProjectionMatrix()

    // 3. 更新 renderer
    renderer.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


网站公告

今日签到

点亮在社区的每一天
去签到