threejs 几何体BufferGeometry

125 阅读3分钟

一、缓冲类型几何体BufferGeometry-点模型

threejs的长方体BoxGeometry、球体SphereGeometry等几何体都是基于BufferGeometry类构建的,BufferGeometry是一个没有任何形状空几何体,你可以通过BufferGeometry自定义任何几何体形状,就是定义顶点数据

points.js

import * as THREE from 'three'

// 创建一个几何体对象
const geometry = new THREE.BufferGeometry()
// 类型化数组创建顶点数据
const vertices = new Float32Array([
  0, 0, 0, //顶点1坐标
  50, 0, 0, //顶点2坐标
  0, 100, 0, //顶点3坐标
])
// 创建属性缓冲区对象,3个为一组,表示一个顶点的xyz坐标
const attribute = new THREE.BufferAttribute(vertices, 3)
// 设置几何体的位置属性
geometry.attributes.position = attribute

// 点渲染模式
const material = new THREE.PointsMaterial({
  color: 'yellow',
  size: 10
})
// 点模型对象
const points = new THREE.Points(geometry, material)

export default points

导入和使用

import points from './02-points.js'

const scene = new THREE.Scene()

// const geometry = new THREE.BoxGeometry(100, 100, 100)

// const material = new THREE.MeshLambertMaterial({
//   color: 'deeppink',
//   transparent: true,
//   opacity: 0.5
// })

// const mesh = new THREE.Mesh(geometry, material)
// scene.add(mesh)
scene.add(points)
image.png

二、线模型

// 线材质
const material = new THREE.LineBasicMaterial({ color: 'yellow' })
// 线模型对象
const points = new THREE.Line(geometry, material)
image.png

三、网格模型

网格模型Mesh是一个个三角形的面拼接而成,多组顶点构成多个三角形,模拟物体的表面

image.png

// 基础网格模型材质
const material = new THREE.MeshBasicMaterial({
  color: 'yellow',
  side: THREE.DoubleSide //两面可见
})
// 网格模型对象
const points = new THREE.Mesh(geometry, material)
image.png
  1. 逆时针:正面(默认)
  2. 顺时针:背面

四、尝试构建一个矩形平面几何体

const vertices = new Float32Array([
  0,0,0,
  50,0,0,
  50,50,0,
  0,0,0,
  50,50,0,
  0,50,0
])

还是使用网格模型对象

image.png

五、几何顶点索引数据

前面例子中有2个顶点坐标是重复的,可以将重复的顶点删除

const vertices = new Float32Array([
  0,0,0,
  50,0,0,
  50,50,0,
  // 0,0,0,
  // 50,50,0,
  0,50,0
])
// Uint16Array类型化数组创建顶点索引数据
const indexs = new Uint16Array([0, 1, 2, 0, 2, 3])
geometry.index = new THREE.BufferAttribute(indexs, 1) // 1个位一组

效果和上面一样

六、顶点法线数据

MeshBasicMaterial材质不受光照影响,当使用受光照影响的材质,如MeshLambertMaterial,几何体需要定义法线数据

// 定义法线,和顶点位置数据对应
const normals = new Float32Array([
  0,0,1, // 顶点1法线
  0,0,1, // 顶点2法线
  0,0,1, // 顶点3法线
  0,0,1 // 顶点4法线
])
geometry.attributes.normal = new THREE.BufferAttribute(normals, 3)

使用非光泽表面的材质MeshLambertMaterial

const material = new THREE.MeshLambertMaterial({
  color: 'yellow',
  side: THREE.DoubleSide //两面可见
})
image.png

七、查看threejs自带几何体顶点

创建一个长方体

const geometry = new THREE.BoxGeometry(50, 50, 50)
console.log('顶点位置数据', geometry.attributes.position)
console.log('顶点索引数据', geometry.index)
const material = new THREE.MeshLambertMaterial({
  color: 'yellow',
})
image.png

wireframe 材质属性

设置为true,线条模式渲染,查看几何体的三角形结构

const material = new THREE.MeshLambertMaterial({
  color: 'yellow',
  wireframe: true
})
image.png

几何体细分数

PlaneGeometry的后2个参数表示细分数,默认为1,可以自定义

const geometry = new THREE.PlaneGeometry(50, 50, 20, 40)

分成了更多的小三角形

image.png

SphereGeometry的细分数默认为32, 16

const geometry = new THREE.SphereGeometry( 50, 32, 16 );
image.png

将细分数设置小一点,球体就不那么光滑

const geometry = new THREE.SphereGeometry( 50, 8, 8 );
image.png

三角形数量与性能

  1. 对于曲面而言,三角形数量越多,表面越光滑,三角形的顶点数据也会越多
  2. 三角形顶点数据会影响threejs的渲染性能,在不影响渲染效果的情况下,三角形顶点数量越少越好

八、旋转、缩放、平移几何体

x,y,z轴都缩小至原来的一半

geometry.scale(0.5, 0.5, 0.5)

沿着x轴负半轴平移50

geometry.translate(-50, 0, 0);

几何体绕着x轴旋转45度

geometry.rotateX(Math.PI / 4)

居中

geometry.center()