【ThreeJS Basics 08】Geometries 几何

96 阅读5分钟

几何

三个点可以确定一个面,可以连接成一个三角形

Three.js 中,几何图形由顶点(3D 空间中的点坐标)和面(连接这些顶点以创建表面的三角形)组成。 我们使用几何图形来创建网格,但您也可以使用几何图形来形成粒子。每个顶点(顶点的单数)将对应一个粒子,但这是以后的课程内容。 我们可以在顶点中存储比位置更多的数据。一个很好的例子是讨论 UV 坐标或法线。正如你所看到的,我们稍后会详细了解这些内容。

不同的内置几何形状

ThreeJS 中内置了很多盒子

BoxGeometry 创建一个盒子

threejs.org/docs/#api/e…

在这里插入图片描述

PlaneGeometry 创建一个矩形平面

threejs.org/docs/#api/e…

在这里插入图片描述

CircleGeometry 创建一个圆盘或圆盘的一部分(类似饼图)

threejs.org/docs/#api/e…

在这里插入图片描述

ConeGeometry 创建圆锥体或圆锥体的一部分(可以打开或关闭圆锥体的底部)

threejs.org/docs/#api/e…

在这里插入图片描述

CylinderGeometry 创建一个圆柱体 (可以打开或关闭圆柱体的末端,并且可以更改每个末端的半径)

threejs.org/docs/#api/e…

在这里插入图片描述

RingGeometry 创建平面环或平面圆的一部分

threejs.org/docs/#api/e…

在这里插入图片描述

TorusGeometry 创建具有厚度(像甜甜圈)或环的一部分的环

threejs.org/docs/#api/e…

在这里插入图片描述

TorusKnotGeometry 创建某种结几何

threejs.org/docs/#api/e…

在这里插入图片描述

DodecahedronGeometry 十二面体几何体

创建一个有 12 个面的球体(可以添加细节以使球体更圆)

threejs.org/docs/#api/e…

在这里插入图片描述

OctahedronGeometry 八面体几何体 创建一个 8 面球体

(可以添加细节以使球体更圆)

threejs.org/docs/#api/e…

在这里插入图片描述

TetrahedronGeometry 四面体几何体

threejs.org/docs/#api/e…

创建一个 4 面球体(如果不增加细节,它就不怎么像球体,可以添加细节来使球体更圆)

在这里插入图片描述

IcosahedronGeometry 二十面体几何体

创建一个由大小大致相同的三角形组成的球体

threejs.org/docs/#api/e…

在这里插入图片描述

SphereGeometry 创建最流行的球体类型

其面看起来像四边形(四边形只是两个三角形的组合)

threejs.org/docs/#api/e…

在这里插入图片描述

ShapeGeometry 基于路径创建形状

threejs.org/docs/#api/e…

在这里插入图片描述

TubeGeometry 创建一个沿路径的管道

threejs.org/docs/#api/e…

在这里插入图片描述

ExtrudeGeometry 根据路径创建挤压

可以添加和控制斜面 threejs.org/docs/#api/e…

在这里插入图片描述

LatheGeometry 创建花瓶或花瓶的一部分

threejs.org/docs/#api/e…

在这里插入图片描述

TextGeometry 创建 3D 文本

您必须提供字体 json 格式的字体

threejs.org/docs/?q=tex…

在这里插入图片描述


BoxGeometry 盒子

还是拿最普遍的的盒子来举例子

我们已经制作了一个立方体,但我们没有谈论太多参数。大多数几何图形都有参数,在使用它之前,你应该先查看文档。

盒子有六个参数,分别是

widthx:轴上的大小 heighty:轴上的大小 depthz:轴上的大小 widthSegmentsx:轴上有多少个细分 heightSegmentsy:轴上有多少个细分 depthSegmentsz:轴上有多少个细分

const geometry = new THREE.BoxGeometry(1, 1, 1, 2, 2, 2)

问题是我们看不到这些三角形。

一个好的解决方案是添加 wireframe: true 到我们的材质中。线框将显示界定每个三角形的线:

const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })

在这里插入图片描述 可以看到,一个面上有八个三角形

我们添加的细分越多,我们能区分的面就越少。但请记住,太多的顶点和面会影响性能。

创建自定义的缓冲区几何图形

有时,我们需要创建自己的几何图形。如果几何图形非常复杂或具有精确的形状,最好在 3D 软件中创建它(我们将在以后的课程中介绍这一点),但如果几何图形不太复杂,我们可以使用 BufferGeometry 自己构建它。

要创建自己的缓冲区几何体,首先实例化一个空的 BufferGeometry 我们将创建一个简单的三角形:

// Create an empty BufferGeometry
const geometry = new THREE.BufferGeometry()

要将顶点添加到 BufferGeometry ,您必须从 Float32Array 开始。

Float32Array 是原生 JavaScript 类型的数组。你只能在其中存储浮点数,并且该数组的长度是固定的。

要创建 Float32Array,您可以指定其长度,然后稍后填充它:

const positionsArray = new Float32Array(9)

// First vertice
positionsArray[0] = 0
positionsArray[1] = 0
positionsArray[2] = 0

// Second vertice
positionsArray[3] = 0
positionsArray[4] = 1
positionsArray[5] = 0

// Third vertice
positionsArray[6] = 1
positionsArray[7] = 0
positionsArray[8] = 0

或者用矩阵

const positionsArray = new Float32Array([
    0, 0, 0, // First vertex
    0, 1, 0, // Second vertex
    1, 0, 0  // Third vertex
])

如您所见,顶点的坐标是线性指定的。该数组是一个一维数组,其中您指定第一个顶点的x、y和z,然后指定第二个顶点的 、和,依此类推x。yz

在将该数组发送到 BufferGeometry 之前,您必须将其转换为 BufferAttribute

第一个参数对应于你的类型数组,第二个参数对应于一个顶点属性由多少个值组成。如前所述,要读取此数组,我们必须 3x3 遍历,因为顶点位置由 3 个值组成(x、y和z):

const positionsAttribute = new THREE.BufferAttribute(positionsArray, 3)

然后我们可以使用该方法将该属性添加到我们的 BufferGeometrysetAttribute(...) 中。第一个参数是该属性的名称,第二个参数是值:

geometry.setAttribute('position', positionsAttribute)

我们选择 'position' 这个名称是因为 Three.js 内部着色器会查找该值来定位顶点。我们将在着色器课程中看到更多相关内容

面将按照顶点的顺序自动创建

在这里插入图片描述 我们还可以创建一堆随机三角形:

// Create an empty BufferGeometry
const geometry = new THREE.BufferGeometry()

// Create 50 triangles (450 values)
const count = 50
const positionsArray = new Float32Array(count * 3 * 3)
for(let i = 0; i < count * 3 * 3; i++)
{
    positionsArray[i] = (Math.random() - 0.5) * 4
}

// Create the attribute and name it 'position'
const positionsAttribute = new THREE.BufferAttribute(positionsArray, 3)
geometry.setAttribute('position', positionsAttribute)

在这里插入图片描述

唯一的困难可能是 count * 3 * 3部分,但解释起来相当简单: 我们需要50三角形。每个三角形由顶点组成,每个顶点由值(x,y,z) 组成。3xyz

指数

BufferGeometry 的一个有趣之处在于,您可以使用该 index 属性来相互化顶点。考虑一个立方体。多个面可以使用一些顶点,例如角落中的顶点。如果仔细观察,每个顶点都可以被各种相邻三角形使用。这将导致属性数组更小,性能得到提升。但我们不会在那节课中介绍这部分内容。