跳到主要内容

学习使用几何体

在前几章中,您学到了许多关于如何使用 Three.js 的知识。 现在您已经知道如何创建基本场景、添加光照并配置网格的材质。 在第2章《Three.js场景的基本组件》中, 我们简要涉及了(但并未深入讨论)Three.js提供的几何体的详细信息, 您可以使用这些几何体来创建您的3D对象。 在本章和第6章《探索高级几何体》中, 我们将为您介绍 Three.js 提供的所有开箱即用的几何体(除了我们在第4章《使用Three.js材质》中讨论的 THREE.Line)。

在本章中,我们将研究以下几何体:

  • THREE.CircleGeometry
  • THREE.RingGeometry
  • THREE.PlaneGeometry
  • THREE.ShapeGeometry
  • THREE.BoxGeometry
  • THREE.SphereGeometry
  • THREE.CylinderGeometry
  • THREE.ConeGeometry
  • THREE.TorusGeometry
  • THREE.TorusKnotGeometry
  • THREE.PolyhedronGeometry
  • THREE.IcosahedronGeometry
  • THREE.OctahedronGeometry
  • THREE.TetrahedronGeometry
  • THREE.DodecahedronGeometry

在深入研究 Three.js 提供的几何体之前, 我们首先将更深入地了解 Three.js 如何将几何体内部表示为 THREE.BufferGeometry。 在一些文档中,您可能仍会遇到 THREE.Geometry 作为所有几何体的基础对象。 在更新的版本中,这已经完全被 THREE.BufferGeometry 取代,后者通常具有更好的性能, 因为它可以轻松地将数据传输到 GPU。 然而,与旧的 THREE.Geometry 相比,使用起来稍微有些困难。

使用 THREE.BufferGeometry,几何体的所有属性都由一组属性标识。属性基本上是一个带有一些附加元数据的数组,其中包含有关顶点位置的信息。属性还用于存储有关顶点的其他信息,例如颜色。要使用属性定义顶点和面,您可以使用 THREE.BufferGeometry 的以下两个属性:

  • attributesattributes 属性用于存储可以直接传递给 GPU 的信息。 例如,为了定义一个形状,您可以定义一个 Float32Array,其中每三个值定义一个顶点。 然后可以在 THREE.BufferGeometry 中这样定义:geometry.setAttribute('position', new THREE.BufferAttribute(arrayOfVertices, 3));
  • index:默认情况下,不需要显式定义面(每三个连续的位置被解释为一个单独的面), 但使用 index 属性, 我们可以显式定义哪些顶点一起形成一个面:geometry.setIndex(indicesArray);

在本章中,使用这些内部属性创建几何体时,您无需考虑这些内部属性, 因为当构造几何体时,Three.js 会正确设置它们。 然而,如果您想从头开始创建几何体,那么您需要使用前面列表中显示的属性。

在 Three.js 中,我们有一些几何体会产生 2D 网格,以及更多会创建 3D 网格的几何体。 在本章中,我们将讨论以下主题:

  • 2D 几何体
  • 3D 几何体

2D 几何体

2D 对象看起来像是平面对象,并且顾名思义,只有两个维度。 在本节中,我们将首先看一下 2D 几何体: THREE.CircleGeometryTHREE.RingGeometryTHREE.PlaneGeometryTHREE.ShapeGeometry

THREE.PlaneGeometry

THREE.PlaneGeometry 对象可用于创建一个非常简单的 2D 矩形。 要查看此几何体的示例,请查看本章节源代码中的 plane-geometry.html 示例。 以下截图显示了使用 THREE.PlaneGeometry 创建的矩形:

在本章的示例中,我们添加了一个控制 GUI,您可以使用它来控制几何体的属性(在本例中为宽度、高度、宽度分段数和高度分段数),还可以更改材质(及其属性)、禁用阴影并隐藏地平面。例如,如果要查看此形状的各个面,可以通过禁用地平面并启用所选材质的 wireframe 属性来轻松显示它们:

创建 THREE.PlaneGeometry 对象非常简单,如下所示:

new THREE.PlaneGeometry(width, height, widthSegments, heightSegments)

THREE.PlaneGeometry 的这个示例中, 您可以更改这些属性并直接看到其对生成的 3D 对象的影响。 下面是这些属性的解释:

  • width:矩形的宽度。
  • height:矩形的高度。
  • widthSegments:应将宽度划分为的段数。默认为1。
  • heightSegments:应将高度划分为的段数。默认为1。

如您所见,这不是一个非常复杂的几何体。您只需指定大小,就完成了。 如果要创建更多的面(例如,当您想创建棋盘图案时),可以使用 widthSegmentsheightSegments 属性将几何体划分为较小的面。

备注

如果要在创建后访问几何体的属性,不能简单地说 plane.width。 要访问几何体的属性,必须使用对象的 parameters 属性。 因此,要获取本节中创建的 plane 对象的宽度属性, 您需要使用 plane.parameters.width

THREE.CircleGeometry

您可能已经猜到 THREE.CircleGeometry 创建的是什么。 使用这个几何体,您可以创建一个非常简单的 2D 圆形(或部分圆形)。 首先,让我们看一下这个几何体的示例,即 circle-geometry.html

在下面的截图中,您可以找到一个示例, 我们在其中使用了 THREE.CircleGeometry 对象, 其 thetaLength 值小于 2 * PI

在这个例子中,您可以看到并控制通过使用 THREE.CircleGeometry 创建的一个网格。 2 * PI 代表弧度中的完整圆。如果您更喜欢使用度而不是弧度, 它们之间的转换非常简单。

以下两个函数可以帮助您在弧度和度之间进行转换:

const deg2rad = (degrees) => (degrees * Math.PI) / 180
const rad2deg = (radians) => (radians * 180) / Math.PI

在创建 THREE.CircleGeometry 时,您可以指定一些定义圆形外观的属性,如下:

  • radius:圆的半径定义了其大小。半径是从圆心到其边缘的距离。默认值为 50
  • segments:此属性定义用于创建圆的面的数量。最小数量为 3, 如果未指定,此数字默认为 8。较大的值表示更平滑的圆。
  • thetaStart:此属性定义从何处开始绘制圆。此值可在 02 * PI 范围内,其默认值为 0
  • thetaLength:此属性定义圆的完整程度。当未指定时,默认为 2 * PI(完整圆)。 例如,如果为此值指定了 0.5 * PI,则将获得一个四分之一的圆。 结合 thetaStart 属性使用此属性来定义圆的形状。

您可以通过仅指定半径和段数来创建一个完整的圆:

new THREE.CircleGeometry(3, 12)

如果您想从这个几何体创建半圆,可以使用类似以下的方法:

new THREE.CircleGeometry(3, 12, 0, Math.PI);

这将创建一个半径为 3、分为 12 段的圆。圆从默认值 0 开始绘制, 并且仅绘制一半,因为我们将 thetaLength 指定为 Math.PI,即半个圆。

在转到下一个几何体之前, 这里有一个关于 Three.js 在创建这些 2D 形状( THREE.PlaneGeometryTHREE.CircleGeometryTHREE.RingGeometryTHREE.ShapeGeometry)时使用的方向的简短说明: Three.js 创建这些对象时,它们是直立的,因此它们沿着 x-y 平面对齐。 这在逻辑上是非常合理的,因为它们是 2D 形状。 然而,通常,特别是对于 THREE.PlaneGeometry, 您可能希望将网格放置在地面上(x-z 平面上), 作为可以放置其余对象的某种地面区域。 创建一个横向而不是纵向的 2D 对象的最简单方法是将网格围绕其 x 轴进行一个四分之一的反向旋转(-PI/2),如下所示:

mesh.rotation.x = -Math.PI/2;

这就是关于 THREE.CircleGeometry 的全部内容。 下一个几何体 THREE.RingGeometry 看起来很像 THREE.CircleGeometry

THREE.RingGeometry

使用 THREE.RingGeometry,您可以创建一个与 THREE.CircleGeometry 非常相似的 2D 对象, 但它还允许您在中心定义一个孔(请参见 ring-geometry.html):

在创建 THREE.RingGeometry 对象时,您可以使用以下属性:

  • innerRadius:圆的内半径定义了中心孔的大小。如果此属性设置为 0,则不会显示孔。默认值为 0
  • outerRadius:圆的外半径定义了其大小。半径是从圆心到其边缘的距离。默认值为 50
  • thetaSegments:这是用于创建圆的对角线段数。较大的值表示更平滑的环。默认值为 8
  • phiSegments:这是用于沿环长度使用的段数。默认值为 8。这实际上并不影响圆的平滑度,但增加了面的数量。
  • thetaStart:这定义了从何处开始绘制圆。此值可以在 02 * PI 范围内,其默认值为 0
  • thetaLength:这定义了圆的完整程度。当未指定时,默认为 2 * PI(完整圆)。例如,如果为此值指定了 0.5 * PI,则将获得一个四分之一的圆。结合 thetaStart 属性使用此属性来定义环的形状。

下面的截图展示了 thetaStartthetaLengthTHREE.RingGeometry 中的工作方式:

在下一节,我们将查看最后一个 2D 形状:THREE.ShapeGeometry

THREE.ShapeGeometry

THREE.PlaneGeometryTHREE.CircleGeometry 在定制外观方面有一些限制。 如果您想创建自定义的 2D 形状,您可以使用 THREE.ShapeGeometry。 使用 THREE.ShapeGeometry,您可以调用一些函数来创建自己的形状。 您可以将此功能与 <path/> 元素功能进行比较,该功能还可用于 HTML 画布元素和 SVG。 让我们从一个示例开始,然后我们将向您展示如何使用各种函数来绘制自己的形状。 shape-geometry.html 示例可以在本章的源代码中找到。

下面的截图显示了这个示例:

在这个例子中,您可以看到一个自定义创建的 2D 形状。 在描述属性之前,首先让我们看一下用于创建此形状的代码。 在创建 THREE.ShapeGeometry 对象之前,我们首先必须创建一个 THREE.Shape 对象。 您可以通过查看前面的截图,从中我们从右下角开始,追踪这些步骤。 这是我们创建 THREE.Shape 对象的方式:

const drawShape = () => {
// create a basic shape
const shape = new THREE.Shape()
// startpoint
// straight line upwards
shape.lineTo(10, 40)
// the top of the figure, curve to the right
shape.bezierCurveTo(15, 25, 25, 25, 30, 40)
// spline back down
shape.splineThru([new THREE.Vector2(32, 30), new THREE.Vector2(28, 20), new THREE.Vector2(30, 10)])
// add 'eye' hole one
const hole1 = new THREE.Path()
hole1.absellipse(16, 24, 2, 3, 0, Math.PI * 2, true)
shape.holes.push(hole1)
// add 'eye hole 2'
const hole2 = new THREE.Path()
hole2.absellipse(23, 24, 2, 3, 0, Math.PI * 2, true)
shape.holes.push(hole2)
// add 'mouth'
const hole3 = new THREE.Path()
hole3.absarc(20, 16, 2, 0, Math.PI, true)
shape.holes.push(hole3)
return shape
}

在这段代码中,您可以看到我们使用线、曲线和样条线来创建此形状的轮廓。 之后,我们通过使用 THREE.Shapeholes 属性将一些孔打在这个形状中。

然而,在本节中,我们讨论的是 THREE.ShapeGeometry 而不是 THREE.Shape - 要从 THREE.Shape 创建几何体, 我们需要将 THREE.Shape(在我们的例子中从 drawShape() 函数返回) 作为参数传递给 THREE.ShapeGeometry。 您还可以传递一个 THREE.Shape 对象数组作为第二个参数, 但在我们的示例中,我们只使用一个对象:

new THREE.ShapeGeometry(drawShape())

此函数的结果是一个几何体,可用于创建一个网格。 除了要转换为 THREE.ShapeGeometry 的形状之外, 您还可以将一些附加选项对象作为第二个参数传递:

  • curveSegments:此属性确定从形状创建的曲线的平滑程度。默认值为 12
  • material:这是用于为指定形状创建的面指定的 materialIndex 属性。 因此,如果传入多个材料,您可以指定应将哪些材料应用于创建的形状的面。
  • UVGenerator:当在材质中使用纹理时,UV 映射确定用于特定面的纹理的部分。 通过 UVGenerator 属性,您可以传递自己的对象,该对象将为传入的形状创建面的 UV 设置。 有关 UV 设置的更多信息,请参见第 10 章,加载和使用纹理。 如果未指定,则使用 THREE.ExtrudeGeometry.WorldUVGenerator

THREE.ShapeGeometry 的最重要部分是 THREE.Shape,您使用它来创建形状, 因此让我们看一下您可以使用的用于创建 THREE.Shape 的绘制函数列表:

  • moveTo(x, y):将绘图位置移动到指定的 x 和 y 坐标。
  • lineTo(x, y):从当前位置(例如,由 moveTo 函数设置)绘制一条线到提供的 x 和 y 坐标。
  • quadraticCurveTo(aCPx, aCPy, x, y):有两种不同的方法可以指定曲线。 您可以使用 quadraticCurveTo 函数,也可以使用 bezierCurveTo 函数。 这两个函数之间的区别在于您如何指定曲线的曲率。

对于二次曲线,我们需要指定一个额外的点(使用 aCPxaCPy 参数), 曲线仅基于该点和当然是指定的终点(从 xy 参数)。 对于三次曲线(由 bezierCurveTo 函数使用),您需要指定两个额外的点来定义曲线。 路径的起始点是路径的当前位置。

以下图解释了这两个选项之间的区别:

  • bezierCurveTo(aCPx1, aCPy1, aCPx2, aCPy2, x, y):基于提供的参数绘制曲线。 有关解释,请参见前面的列表项。 该曲线基于定义曲线的两个坐标(aCPx1aCPy1aCPx2aCPy2) 以及终点坐标(xy)进行绘制。起始点是路径的当前位置。
  • splineThru(pts):此函数通过提供的坐标集(pts)绘制流线型线。 此参数应为包含 THREE.Vector2 对象的数组。起始点是路径的当前位置。
  • arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise):绘制圆圈(或部分圆圈)。 圆圈从路径的当前位置开始。在这里,aXaY 用作当前位置的偏移量。 请注意,aRadius 设置圆圈的大小,aStartAngleaEndAngle 定义要绘制的圆圈的部分大小。 布尔值 aClockwise 属性确定是顺时针还是逆时针绘制圆圈。
  • absArc(aX, aY, aRadius, aStartAngle, aEndAngle, AClockwise):参见 arc 属性的描述。 该位置是绝对的,而不是相对于当前位置。
  • ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise):参见 arc 属性的描述。 除此之外,通过 ellipse 函数,我们可以分别设置 x 半径和 y 半径。
  • absEllipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise):参见 ellipse 属性的描述。 该位置是绝对的,而不是相对于当前位置。
  • fromPoints(vectors):如果将 THREE.Vector2(或 THREE.Vector3)对象的数组传递给此函数, 则 Three.js 将使用从提供的向量绘制的直线创建路径。
  • holesholes 属性包含一个 THREE.Shape 对象的数组。 此数组中的每个对象都渲染为一个孔。 我们在本节开始时看到的示例代码片段中,我们向此数组添加了三个 THREE.Shape 对象: 一个用于左眼,一个用于右眼,以及一个用于主要 THREE.Shape 对象的嘴巴。

与很多示例一样,要了解各种属性如何影响最终形状, 最简单的方法就是在材质上启用 wireframe 属性并调整设置。 例如,以下截图显示了在 curveSegments 的值较低时会发生什么:

如您所见,形状失去了它漂亮的圆边缘,但在此过程中使用了更少的面。 至于 2D 形状,就是这样。 接下来的部分将展示和解释基本的 3D 形状。

3D几何图形

在这个关于基本3D几何图形的部分,我们将从一个我们已经看过几次的几何图形开始:THREE.BoxGeometry。

THREE.BoxGeometry

THREE.BoxGeometry是一个非常简单的3D几何图形,允许您通过指定其width、height和depth属性来创建一个立方体。我们添加了一个示例,box-geometry.html,在这里您可以调整这些属性。以下截图显示了这个几何图形:

如您在此示例中所见,通过更改THREE.BoxGeometry的width、height和depth属性,您可以控制生成的网格的大小。在创建新的立方体时,这三个属性也是必需的,如下所示:

new THREE.BoxGeometry(10, 10, 10);

在示例中,您还可以看到可以在立方体上定义的一些其他属性。以下是解释所有属性的列表:

  • width:这是立方体的宽度。这是沿x轴的立方体顶点的长度。
  • height:这是立方体的高度。这是沿y轴的立方体顶点的长度。
  • depth:这是立方体的深度。这是沿z轴的立方体顶点的长度。
  • widthSegments:这是我们沿立方体的x轴将面划分为的段数。默认值为1。定义的段数越多,一侧就有越多的面。如果将此属性和接下来的两个属性都设置为1,则立方体的每一侧将只有2个面。如果将此属性设置为2,则该面将被划分为2个段,从而产生4个面。
  • heightSegments:这是我们沿立方体的y轴将面划分为的段数。默认值为1。
  • depthSegments:这是我们沿立方体的z轴将面划分为的段数。默认值为1。

通过增加各种段属性,您可以将立方体的六个主要面划分为更小的面。如果您想要使用THREE.MeshFaceMaterial在立方体的部分上设置特定的材质属性,这是很有用的。

THREE.BoxGeometry是一个非常简单的几何形状。另一个简单的形状是THREE.SphereGeometry。

THREE.SphereGeometry

使用THREE.SphereGeometry,您可以创建一个3D球体。 让我们直接进入示例,sphere-geometry.html

在上面的截图中,我们展示了一个基于THREE.SphereGeometry创建的半开放球体。 这个几何图形非常灵活,可以用来创建各种与球体有关的几何图形。 然而,一个基本的THREE.SphereGeometry实例可以像这样轻松创建:new THREE.SphereGeometry()

以下属性可用于调整生成的网格的外观:

  • radius:用于设置球体的半径。这定义了生成的网格有多大。默认值为50
  • widthSegments:要垂直使用的段数。更多的段数意味着更光滑的表面。默认值为8,最小值为3
  • heightSegments:要水平使用的段数。段数越多,球体表面越光滑。默认值为6,最小值为2
  • phiStart:确定从x轴的哪个位置开始绘制球体。它的范围是从02 * PI。默认值为0
  • phiLength:确定球体从phiStart处到何处绘制。 2 * PI将绘制一个完整的球体,0.5 * PI将绘制一个开放的四分之一球体。默认值是2 * PI
  • thetaStart:确定从x轴的哪个位置开始绘制球体。它的范围是从0到2 * PI, 默认值为0
  • thetaLength:确定球体从thetaStart处绘制到何处。 2 * PI值是一个完整的球体,而PI将只绘制球体的一半。默认值是2 * PI

radiuswidthSegmentsheightSegments属性应该很清楚, 我们在其他示例中已经看到了这些类型的属性。 phiStartphiLengththetaStartthetaLength属性在没有示例的情况下可能有点难以理解。 幸运的是,您可以从sphere-geometry.html示例的菜单中尝试这些属性, 并创建有趣的几何图形,比如这些:

接下来的一个是THREE.CylinderGeometry

THREE.CylinderGeometry

使用这个几何图形,我们可以创建圆柱体和圆柱形物体。 与所有其他几何图形一样,我们也有一个示例(cylinder-geometry.html), 让您可以尝试该几何图形的属性,其截图如下:

当您创建THREE.CylinderGeometry时,没有任何强制性的参数, 因此您可以通过简单调用new THREE.CylinderGeometry()来创建一个圆柱体。 您可以传递一些属性,如前面的示例所示,以更改此圆柱体的外观。 这些属性在以下列表中解释:

  • radiusTop:设置此圆柱体顶部的大小。默认值为20
  • radiusBottom:设置此圆柱体底部的大小。默认值为20
  • height:此属性设置圆柱体的高度。默认高度为100
  • radialSegments:确定沿圆柱体半径的段数。默认为8。更多的段数意味着更光滑的圆柱体。
  • heightSegments:确定沿圆柱体高度的段数。默认值为1。更多的段数意味着更多的面。
  • openEnded:确定网格在顶部和底部是否封闭。默认值为false
  • thetaStart:确定沿其x轴从何处开始绘制圆柱体。 这可以在02 * PI之间变化,默认值为0
  • thetaLength:确定圆柱体从thetaStart处绘制到何处。 2 * PI值是一个完整的圆柱体,而PI将只绘制半个圆柱体。默认值是2 * PI

这些都是您可以用来配置圆柱体的非常基本的属性。 然而,一个有趣的方面是当您为顶部(或底部)使用负半径值时。 如果这样做,您可以使用这个几何体创建类似沙漏的形状,如下截图所示:

这里需要注意的一点是,这种情况下的顶部半部分被翻转了。 如果使用未配置为THREE.DoubleSide的材质,您将看不到顶部半部分。

接下来的几何图形是THREE.ConeGeometry, 它提供了THREE.CylinderGeometry的基本功能,但将顶部半径固定为零。

THREE.ConeGeometry

THREE.ConeGeometryTHREE.CylinderGeometry几乎相同。 它使用相同的所有属性,只允许您设置半径,而不是分别设置radiusTopradiusBottom值:

以下属性可在THREE.ConeGeometry上设置:

  • radius:设置此圆锥体底部的大小。默认值为20
  • height:此属性设置圆锥体的高度。默认高度为100
  • radialSegments:确定沿圆锥体半径的段数。默认为8。更多的段数意味着更光滑的圆锥体。
  • heightSegments:确定沿圆锥体高度的段数。默认值为1。更多的段数意味着更多的面。
  • openEnded:确定网格在顶部和底部是否封闭。默认值为false
  • thetaStart:确定沿其x轴从何处开始绘制圆锥体。这可以在02 * PI之间变化,默认值为0
  • thetaLength:确定圆锥体从thetaStart处绘制到何处。 2 * PI值是一个完整的圆锥体,而PI将只绘制半个圆锥体。默认值是2 * PI

接下来的几何图形是THREE.TorusGeometry,允许您创建类似甜甜圈形状的对象。

THREE.TorusGeometry

环面是一个简单的形状,看起来像一个甜甜圈。 通过打开torus-geometry.html示例,您可以自行获得以下截图, 展示了THREE.TorusGeometry的实际效果:

就像大多数简单的几何图形一样,创建THREE.TorusGeometry时没有任何强制性的参数。 以下列表提到了在创建此几何体时可以指定的参数:

  • radius:设置完整环面的大小。默认值为100
  • tube:设置管道(实际上是甜甜圈)的半径。此属性的默认值为40
  • radialSegments:确定沿着环面长度使用的段数。默认值为8。在示例中查看更改此值的效果。
  • tubularSegments:确定沿着环面宽度使用的段数。默认值为6。在示例中查看更改此值的效果。
  • arc:使用此属性,您可以控制环面是否绘制完整圆圈。此值的默认值为2 * PI(完整圆圈)。

这些大多数都是您已经见过的非常基本的属性。 然而,arc属性是一个非常有趣的属性。 通过使用此属性,您可以定义甜甜圈是绘制完整圆圈还是部分圆圈。 通过尝试此属性,您可以创建非常有趣的网格,例如将arc设置为低于2 * PI的值时的以下网格:

THREE.TorusGeometry是一个非常直观的几何体。 在下一节中,我们将看到一个几何体,它几乎与其名称相似,但却更加复杂:THREE.TorusKnotGeometry

THREE.TorusKnotGeometry

使用THREE.TorusKnotGeometry,您可以创建一个环形结。 环形结是一种特殊类型的结,看起来像是一个围绕自身几次的管道。 最好的解释是通过查看torus-knot-geometry.html示例。 以下截图显示了这个几何体:

如果您打开此示例并尝试pq属性,您可以创建各种美丽的几何图形。 p属性定义结环绕其轴的次数,q定义结在其内部环绕的程度。

如果这听起来有点模糊,别担心。 您不需要理解这些属性就可以创建美丽的结, 例如以下截图中显示的结(对于那些对细节感兴趣的人, Wolfram在https://mathworld.wolfram.com/TorusKnot.html上有一篇很好的文章):

通过此几何体的示例,您可以尝试以下属性,并查看p和q的各种组合对此几何体的影响:

  • radius:设置完整环形结的大小。默认值为100
  • tube:设置管道(实际上是甜甜圈)的半径。此属性的默认值为40
  • radialSegments:确定沿着环形结长度使用的段数。默认值为64。在演示中查看更改此值的效果。
  • tubularSegments:确定沿着环形结宽度使用的段数。默认值为8。在演示中查看更改此值的效果。
  • p:定义结的形状,其默认值为2
  • q:定义结的形状,其默认值为3
  • heightScale:使用此属性,您可以拉伸环形结。默认值为1

列表中的下一个几何体是基本几何体中的最后一个:THREE.PolyhedronGeometry

THREE.PolyhedronGeometry

使用这个几何体,您可以轻松创建多面体。 多面体是一个只有平坦面和直线边的几何体。 然而,大多数情况下,您不会直接使用THREE.PolyhedronGeometry。 Three.js提供了许多特定的多面体,您可以使用而无需指定THREE.PolyhedronGeometry的顶点和面。

如果您确实想直接使用THREE.PolyhedronGeometry, 您必须指定顶点和面(就像我们在第3章Three.js中的光源处理中为立方体所做的那样)。 例如,我们可以创建一个简单的四面体(还可以在本章关于THREE.TetrahedronGeometry的部分中查看) 如下:

const vertices = [
1, 1, 1,
-1, -1, 1,
-1, 1, -1,
1, -1, -1
];
const indices = [
2, 1, 0,
0, 3, 2,
1, 3, 0,
2, 3, 1
];
new THREE.PolyhedronBufferGeometry(vertices, indices, radius, detail);

要构建THREE.PolyhedronGeometry,我们传递顶点、索引、半径和详细属性。 生成的THREE.PolyhedronGeometry对象显示在polyhedron-geometry.html示例中:

创建多面体时,可以传递以下四个属性:

  • vertices:构成多面体的点。
  • indices:需要从这些点创建的面。
  • radius:多面体的大小。默认为1
  • detail:使用此属性,您可以为多面体添加附加细节。 如果将其设置为1,多面体中的每个三角形将分成4个更小的三角形。 如果将其设置为2,这4个更小的三角形将再次分成4个更小的三角形,依此类推。

以下截图显示了相同的自定义网格,但现在具有更高的详细级别:

在本节的开头,我们提到了Three.js带有一些预设的多面体。 在以下子节中,我们将快速向您展示这些。 可以通过查看polyhedron-geometry.html示例查看所有这些多面体类型。

THREE.IcosahedronGeometry

THREE.IcosahedronGeometry创建一个多面体, 具有由12个顶点创建的20个相同的三角形面。 在创建此多面体时,您只需指定半径和详细级别。 以下截图显示使用THREE.IcosahedronGeometry创建的多面体:

接下来,我们将看到一个具有八个面的多面体:八面体。

THREE.TetrahedronGeometry

四面体是最简单的多面体之一。这个多面体仅包含由四个顶点创建的四个三角形面。 您可以像使用Three.js提供的其他多面体一样, 通过指定半径和详细级别来创建THREE.TetrahedronGeometry。 以下截图显示使用THREE.TetrahedronGeometry创建的四面体:

接下来,我们将看到一个具有八个面的多面体:八面体。

THREE.OctahedronGeometry

Three.js还提供了一个八面体的实现。 正如其名称所示,这个多面体有八个面。 这些面是由六个顶点创建的。以下截图显示了此几何体:

我们要查看的多面体中的最后一个是十二面体。

THREE.DodecahedronGeometry

Three.js提供的最后一个多面体几何体是THREE.DodecahedronGeometry。 这个多面体有12个面。以下截图显示了此几何体:

正如您所看到的,Three.js提供了大量的3D几何体,从直接有用的几何体, 如球体和立方体,到在实践中可能不太有用的多面体集。 无论如何,这些3D几何体都将为您创建和实验材质、几何体和3D场景提供一个良好的起点。

总结

在本章中,我们讨论了Three.js提供的所有标准几何体。 正如您所看到的,有很多几何体可以直接使用。 要最好地学习如何使用这些几何体,尝试使用它们。 使用本章中的示例来了解可以用于自定义Three.js提供的标准几何体的属性。

对于2D形状,重要的是要记住它们位于x-y平面上。 如果您想水平放置一个2D形状,您将不得不将网格围绕x轴旋转-0.5 * PI。 最后,请注意,如果您旋转一个2D形状,或者是一个开放的3D形状(例如,一个圆柱或一个管道), 请记得将材质设置为THREE.DoubleSide。如果不这样做,您的几何体的内部或背面将不会显示。

在本章中,我们专注于简单、直观的网格。Three.js还提供了创建复杂几何体的方法,我们将在第6章中介绍。