【Three.js】第九章 Geometries 几何图形

09.Geometries 几何图形

介绍

到目前为止,我们只使用BoxGeometry类来创建我们的立方体。在本课中,我们将发现各种其他几何图形,但首先,我们需要了解几何图形的真正含义。

什么是几何?

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

不同的内置几何形状

Three.js 有很多内置的几何图形。虽然您不需要确切地知道如何实例化每一个,但最好知道它们的存在。
我们将看到的所有内置几何图形都继承自BufferGeometry类。此类有许多内置方法,例如translate(...)rotateX(...)normalize() 等,但我们不会在本课中使用它们。
大多数几何文档页面都有示例。

  • BoxGeometry 创建一个盒子。
  • PlaneGeometry 创建一个矩形平面。
  • CircleGeometry 创建圆盘或圆盘的一部分(如饼图)。
  • ConeGeometry 创建圆锥体或圆锥体的一部分。您可以打开或关闭圆锥体的底部。
  • CylinderGeometry 创建一个圆柱体。您可以打开或关闭圆柱体的两端,并且可以更改每一端的半径。
  • RingGeometry 创建扁平环或扁平圆的一部分。
  • TorusGeometry 创建一个具有厚度(如甜甜圈)或环的一部分的环。
  • TorusKnotGeometry 创建某种几何结。
  • DodecahedronGeometry 创建一个有 12 个面的球体。您可以为更圆的球体添加细节。
  • OctahedronGeometry 创建一个有 8 个面的球体。您可以为更圆的球体添加细节。
  • TetrahedronGeometry 创建一个 4 面球体(如果不增加细节,它不会是一个很大的球体)。您可以为更圆的球体添加细节。
  • IcosahedronGeometry 创建一个由大小大致相同的三角形组成的球体。
  • SphereGeometry 创建最流行的球体类型,其中的面看起来像四边形(四边形只是两个三角形的组合)。
  • ShapeGeometry 根据路径创建形状。
  • TubeGeometry 按照路径创建管。
  • ExtrudeGeometry 根据路径创建挤压。您可以添加和控制斜角。
  • LatheGeometry 创建花瓶或花瓶的一部分(更像是一场革命)。
  • TextGeometry 创建 3D 文本。您必须提供字体 json 格式的字体。

如果您需要 Three.js 不支持的特定特殊几何体,您可以在 JavaScript 中创建自己的几何体,或者您可以在 3D 软件中制作它,将其导出并导入到您的项目中。我们稍后的课程会介绍更多。

框示例

我们已经制作了一个立方体,但我们并没有过多讨论参数。大多数几何图形都有参数,在使用它之前,您应该始终查看文档。
BoxGeometry有 6 个参数

  • widthx:轴上的尺寸
  • heighty:轴上的尺寸
  • depthz:轴上的尺寸
  • widthSegmentsx:轴有多少细分
  • heightSegmentsy:轴有多少细分
  • depthSegmentsz:轴有多少细分

细分对应于构成面部的三角形数量。默认情况下它是1,这意味着每个面只有 2 个三角形。如果将细分设置为2,每个面最终会得到 8 个三角形:

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

问题是我们看不到这些三角形。
一个好的解决方案是添加wireframe: true到我们的材料中。线框将显示分隔每个三角形的线:

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


如您所见,面有 8 个三角形。
虽然这与平面立方体无关,但在使用 SphereGeometry 时会变得更有趣

const geometry = new THREE.SphereGeometry(1, 32, 32)


我们添加的细分越多,图形就越接近完美。但请记住,过多的顶点和面会影响性能。

创建自己的缓冲区几何

有时,我们需要创建自己的几何图形。如果几何体非常复杂或具有精确的形状,最好在 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
])

如您所见,顶点的坐标是线性指定的。该数组是一个一维数组,您可以在其中指定第一个顶点的xyz,然后是第二个顶点的xyz,依此类推。
在将该数组发送到 BufferGeometry 之前您必须将其转换为BufferAttribute
第一个参数对应于您的类型数组,第二个参数对应于一个顶点属性的值。正如我们之前看到的,要读取这个数组,我们必须 3 乘 3,因为顶点位置由 3 个值(x,yz)组成:

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

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

geometry.setAttribute('position', positionsAttribute)

我们选择'position'这个名称是因为 Three.js 内部着色器将查找该值来定位顶点。我们将在着色器课程中看到更多相关信息。
面将按照顶点的顺序自动创建。
全部一起:

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

// Create a Float32Array containing the vertices position (3 by 3)
const positionsArray = new Float32Array([
    0, 0, 0, // First vertex
    0, 1, 0, // Second vertex
    1, 0, 0  // Third vertex
])

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


我们还可以创建一堆随机三角形:

// 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三角形。每个三角形由顶点组成,每个顶点由值3(xyz)组成。

指数Index

BufferGeometry的一件有趣的事情是您可以使用该index属性使顶点相互化,形成成一个立方体。多个面可以使用一些预计的顶点,例如立方体八个角落中的顶点。如果你仔细观察,每个顶点都可以被不同的相邻三角形使用。这将优化出更小的属性数组和性能上的改进。但我们不会在那节课中介绍这部分内容。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值