Three.js-硬要自学系列6 (构建矩形平面、顶点索引、顶点法线数据)

384 阅读3分钟

本章主要学习知识点

  • 学习通过顶点数据来构建一个矩形平面
  • 使用BufferGeometry创建几何体,并设置顶点索引数据
  • 学会设置顶点位置和法线数据,并利用顶点法向量辅助器观察法线

构建矩形平面

创建顶点数据

const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
  0,0,0, 
  2,0,0,
  2,2,0,
  2,2,0,
  0,2,0,
  0,0,0
])
// 设置几何体顶点位置
geometry.setAttribute('position',new THREE.BufferAttribute(vertices,3))

这里有必要说下BufferGeometry,这是一种高性能几何体数据结构,专为 WebGL 的底层顶点缓冲区优化设计的api,Float32Array用来存储顶点数据,BufferAttribute中定义着顶点位置(position)、颜色(color)、法向量(normal)、UV 坐标等信息。

设置材质

const material = new THREE.MeshBasicMaterial({
  color: 'deepskyblue',
  side:THREE.DoubleSide, // 两面可见
  wireframe: true // 线框模式
})

image.png

你可能注意到了side:THREE.DoubleSide,它控制着模型的背面是否可见,真实世界里的平面都是正反两面,你可以尝试将sidewireframe配置注释掉,旋转模型看看背面是否依然可见

顶点索引

顶点索引是一个重复利用顶点数据的优化技巧,可以理解为用“编号”代替“重复写坐标”

假设现在要用两个三角形拼成一个矩形平面

  • 不使用索引: 你需要6个顶点(每个三角形单独写一遍所有顶点坐标)
  • 使用索引: 只需要4个顶点,然后通过索引告诉 GPU 如何复用这些顶点拼出两个三角形

创建顶点数据,这里直接定义4个顶点数据即可

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

使用索引来组合这些顶点

const indexes = new Uint16Array([
  0,1,2,  // 第一个三角形
  0,2,3   // 第二个三角形
])
// 设置几何体顶点索引数据
geometry.setIndex(new THREE.BufferAttribute(indexes,1))

这样我们就不需要使用6个顶点数据了,直接复用了顶点0和顶点2,

image.png

使用索引的好处

  • 节省内存, 避免存储重复的顶点坐标数据
  • 提示渲染性能,数量减少,传输给到gpu的速度就更快了

索引类型选择

  • 顶点数 ≤ 65536 → Uint16Array
  • 顶点数 > 65536 → Uint32Array

顶点法线数据

顶点法线数据可以理解为每个顶点的“方向指示器” ,它决定了光线如何与物体表面交互,直接影响模型的明暗效果和立体感。

假设你用手电筒照射一座石膏像

  • 有正确的法线: 石膏像的凹凸起伏会有自然的明暗过渡,高光和阴影清晰
  • 没有法线或者错误的法线: 石膏像会像白纸一样平坦,所有区域亮度相同

设置顶点法线数据

const normals = new Float32Array([
  0,0,1,
  0,0,1,
  0,0,1,
  0,0,1,
])
// 设置几何体法线
geometry.setAttribute('normal',new THREE.BufferAttribute(normals,3))

如果想要看到法线,就需要借助顶点法线向量辅助器

导入辅助器,并使用

import { VertexNormalsHelper } from 'three/examples/jsm/helpers/VertexNormalsHelper.js'

const normalHelper = new VertexNormalsHelper(mesh, 2, 'red', 1)
scene.add(normalHelper)

添加完成后,你将看到如下四条红色的法线

75.gif

以上案例均可在案例中心查看体验

THREE 案例中心

image.png