几何
三个点可以确定一个面,可以连接成一个三角形
在
Three.js中,几何图形由顶点(3D 空间中的点坐标)和面(连接这些顶点以创建表面的三角形)组成。 我们使用几何图形来创建网格,但您也可以使用几何图形来形成粒子。每个顶点(顶点的单数)将对应一个粒子,但这是以后的课程内容。 我们可以在顶点中存储比位置更多的数据。一个很好的例子是讨论 UV 坐标或法线。正如你所看到的,我们稍后会详细了解这些内容。
不同的内置几何形状
ThreeJS 中内置了很多盒子
BoxGeometry 创建一个盒子
PlaneGeometry 创建一个矩形平面
CircleGeometry 创建一个圆盘或圆盘的一部分(类似饼图)
ConeGeometry 创建圆锥体或圆锥体的一部分(可以打开或关闭圆锥体的底部)
CylinderGeometry 创建一个圆柱体 (可以打开或关闭圆柱体的末端,并且可以更改每个末端的半径)
RingGeometry 创建平面环或平面圆的一部分
TorusGeometry 创建具有厚度(像甜甜圈)或环的一部分的环
TorusKnotGeometry 创建某种结几何
DodecahedronGeometry 十二面体几何体
创建一个有 12 个面的球体(可以添加细节以使球体更圆)
OctahedronGeometry 八面体几何体 创建一个 8 面球体
(可以添加细节以使球体更圆)
TetrahedronGeometry 四面体几何体
创建一个 4 面球体(如果不增加细节,它就不怎么像球体,可以添加细节来使球体更圆)
IcosahedronGeometry 二十面体几何体
创建一个由大小大致相同的三角形组成的球体
SphereGeometry 创建最流行的球体类型
其面看起来像四边形(四边形只是两个三角形的组合)
ShapeGeometry 基于路径创建形状
TubeGeometry 创建一个沿路径的管道
ExtrudeGeometry 根据路径创建挤压
可以添加和控制斜面 threejs.org/docs/#api/e…
LatheGeometry 创建花瓶或花瓶的一部分
TextGeometry 创建 3D 文本
您必须提供字体 json 格式的字体
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 属性来相互化顶点。考虑一个立方体。多个面可以使用一些顶点,例如角落中的顶点。如果仔细观察,每个顶点都可以被各种相邻三角形使用。这将导致属性数组更小,性能得到提升。但我们不会在那节课中介绍这部分内容。