学习使用几何体
在前几章中,您学到了许多关于如何使用 Three.js 的知识。
现在您已经知道如何创建基本场景、添加光照并配置网格的材质。
在第2章《Three.js场景的基本组件》中,
我们简要涉及了(但并未深入讨论)Three.js提供的几何体的详细信息,
您可以使用这些几何体来创建您的3D对象。
在本章和第6章《探索高级几何体》中,
我们将为您介绍 Three.js 提供的所有开箱即用的几何体(除了我们在第4章《使用Three.js材质》中讨论的 THREE.Line)。
在本章中,我们将研究以下几何体:
THREE.CircleGeometryTHREE.RingGeometryTHREE.PlaneGeometryTHREE.ShapeGeometryTHREE.BoxGeometryTHREE.SphereGeometryTHREE.CylinderGeometryTHREE.ConeGeometryTHREE.TorusGeometryTHREE.TorusKnotGeometryTHREE.PolyhedronGeometryTHREE.IcosahedronGeometryTHREE.OctahedronGeometryTHREE.TetrahedronGeometryTHREE.DodecahedronGeometry
在深入研究 Three.js 提供的几何体之前,
我们首先将更深入地了解 Three.js 如何将几何体内部表示为 THREE.BufferGeometry。
在一些文档中,您可能仍会遇到 THREE.Geometry 作为所有几何体的基础对象。
在更新的版本中,这已经完全被 THREE.BufferGeometry 取代,后者通常具有更好的性能,
因为它可以轻松地将数据传输到 GPU。
然而,与旧的 THREE.Geometry 相比,使用起来稍微有些困难。
使用 THREE.BufferGeometry,几何体的所有属性都由一组属性标识。属性基本上是一个带有一些附加元数据的数组,其中包含有关顶点位置的信息。属性还用于存储有关顶点的其他信息,例如颜色。要使用属性定义顶点和面,您可以使用 THREE.BufferGeometry 的以下两个属性:
attributes:attributes属性用于存储可以直接传递给 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.CircleGeometry、
THREE.RingGeometry、
THREE.PlaneGeometry 和
THREE.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。
如您所见,这不是一个非常复杂的几何体。您只需指定大小,就完成了。
如果要创建更多的面(例如,当您想创建棋盘图案时),可以使用 widthSegments 和 heightSegments 属性将几何体划分为较小的面。
如果要在创建后访问几何体的属性,不能简单地说 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:此属性定义从何处开始绘制圆。此值可在0到2 * 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.PlaneGeometry、
THREE.CircleGeometry、
THREE.RingGeometry 和
THREE.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:这定义了从何处开始绘制圆。此值可以在0到2 * PI范围内,其默认值为0。thetaLength:这定义了圆的完整程度。当未指定时,默认为2 * PI(完整圆)。例如,如果为此值指定了0.5 * PI,则将获得一个四分之一的圆。结合thetaStart属性使用此属性来定义环的形状。
下面的截图展示了 thetaStart 和 thetaLength 在 THREE.RingGeometry 中的工作方式:
在下一节,我们将查看最后一个 2D 形状:THREE.ShapeGeometry。
THREE.ShapeGeometry
THREE.PlaneGeometry 和 THREE.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.Shape 的 holes 属性将一些孔打在这个形状中。
然而,在本节中,我们讨论的是 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函数。 这两个函数之间的区别在于您如何指定曲线的曲率。
对于二次曲线,我们需要指定一个额外的点(使用 aCPx 和 aCPy 参数),
曲线仅基于该点和当然是指定的终点(从 x 和 y 参数)。
对于三次曲线(由 bezierCurveTo 函数使用),您需要指定两个额外的点来定义曲线。
路径的起始点是路径的当前位置。
以下图解释了这两个选项之间的区别:
bezierCurveTo(aCPx1, aCPy1, aCPx2, aCPy2, x, y):基于提供的参数绘制曲线。 有关解释,请参见前面的列表项。 该曲线基于定义曲线的两个坐标(aCPx1、aCPy1、aCPx2和aCPy2) 以及终点坐标(x和y)进行绘制。起始点是路径的当前位置。splineThru(pts):此函数通过提供的坐标集(pts)绘制流线型线。 此参数应为包含THREE.Vector2对象的数组。起始点是路径的当前位置。arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise):绘制圆圈(或部分圆圈)。 圆圈从路径的当前位置开始。在这里,aX和aY用作当前位置的偏移量。 请注意,aRadius设置圆圈的大小,aStartAngle和aEndAngle定义要绘制的圆圈的部分大小。 布尔值 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 将使用从提供的向量绘制的直线创建路径。holes:holes属性包含一个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轴的哪个位置开始绘制球体。它的范围是从0到2 * PI。默认值为0。phiLength:确定球体从phiStart处到何处绘制。2 * PI将绘制一个完整的球体,0.5 * PI将绘制一个开放的四分之一球体。默认值是2 * PI。thetaStart:确定从x轴的哪个位置开始绘制球体。它的范围是从0到2 * PI, 默认值为0。thetaLength:确定球体从thetaStart处绘制到何处。2 * PI值是一个完整的球体,而PI将只绘制球体的一半。默认值是2 * PI。
radius、widthSegments和heightSegments属性应该很清楚,
我们在其他示例中已经看到了这些类型的属性。
phiStart、phiLength、thetaStart和thetaLength属性在没有示例的情况下可能有点难以理解。
幸运的是,您可以从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轴从何处开始绘制圆柱体。 这可以在0到2 * PI之间变化,默认值为0。thetaLength:确定圆柱体从thetaStart处绘制到何处。2 * PI值是一个完整的圆柱体,而PI将只绘制半个圆柱体。默认值是2 * PI。
这些都是您可以用来配置圆柱体的非常基本的属性。 然而,一个有趣的方面是当您为顶部(或底部)使用负半径值时。 如果这样做,您可以使用这个几何体创建类似沙漏的形状,如下截图所示:
这里需要注意的一点是,这种情况下的顶部半部分被翻转了。
如果使用未配置为THREE.DoubleSide的材质,您将看不到顶部半部分。
接下来的几何图形是THREE.ConeGeometry,
它提供了THREE.CylinderGeometry的基本功能,但将顶部半径固定为零。
THREE.ConeGeometry
THREE.ConeGeometry与THREE.CylinderGeometry几乎相同。
它使用相同的所有属性,只允许您设置半径,而不是分别设置radiusTop和radiusBottom值:
以下属性可在THREE.ConeGeometry上设置:
radius:设置此圆锥体底部的大小。默认值为20。height:此属性设置圆锥体的高度。默认高度为100。radialSegments:确定沿圆锥体半径的段数。默认为8。更多的段数意味着更光滑的圆锥体。heightSegments:确定沿圆锥体高度的段数。默认值为1。更多的段数意味着更多的面。openEnded:确定网格在顶部和底部是否封闭。默认值为false。thetaStart:确定沿其x轴从何处开始绘制圆锥体。这可以在0到2 * 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示例。
以下截图显示了这个几何体:
如果您打开此示例并尝试p和q属性,您可以创建各种美丽的几何图形。
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章中介绍。