探索高级几何体
在第5章《学习使用几何体》中,我们向您展示了Three.js提供的所有基本几何体。 除了这些基本几何体之外,Three.js还提供了一组更高级和专业化的对象。 在本章中,我们将向您展示这些高级几何体的用法:
- 如何使用高级几何体,例如
THREE.ConvexGeometry、THREE.LatheGeometry、THREE.BoxLineGeometry、THREE.RoundeBoxGeometry、THREE.TeapotGeometry和THREE.TubeGeometry。 - 如何使用
THREE.ExtrudeGeometry从2D形状创建3D形状。 我们将从2D SVG图像创建3D形状,并从2D Three.js形状挤出以创建新颖的3D形状。 - 如果您想自己创建自定义形状,可以继续玩弄我们在前几章中讨论的形状。
然而,Three.js还提供了一个
THREE.ParametricGeometry对象。 使用参数几何体,您可以创建具有可更改形状的几何体。 - 我们还将展示如何使用
THREE.TextGeometry创建3D文本效果, 并向您展示在场景中添加2D文本标签时如何使用Troika库。 - 此外,我们将向您展示如何使用两个辅助几何体,
即
THREE.WireframeGeometry和THREE.EdgesGeometry。 这些辅助几何体使您能够查看其他几何体的更多细节。
我们将从这个列表中的第一个开始,即THREE.ConvexGeometry。
学习高级几何体
在本节中,我们将查看一些先进的Three.js几何体。
我们将从THREE.ConvexGeometry开始,您可以使用它来创建凸包。
THREE.ConvexGeometry
使用THREE.ConvexGeometry,我们可以从一组点创建凸包。
凸包是包围所有这些点的最小形状。
理解这一点最简单的方法是通过查看示例。如果您打开convex-geometry.html示例,
您将看到一组随机点的凸包。以下截图显示了这个几何体:
在这个例子中,我们生成了一组随机点,并基于这些点创建了THREE.ConvexGeometry。
在例子中,您可以使用右侧菜单中的重绘按钮,它将生成20个新点并绘制凸包。
如果您自己尝试这样做,请启用材质的透明度并将不透明度设置为低于1的水平,以查看用于创建此几何体的点。
在这个例子中,这些点被创建为小的THREE.SphereGeometry对象。
要创建THREE.ConvexGeometry,我们需要一组点。
以下代码片段显示了我们如何做到这一点:
const generatePoints = () => {
const spGroup = new THREE.Object3D();
spGroup.name = 'spGroup';
const points = [];
for (let i = 0; i < 20; i++) {
const randomX = -5 + Math.round(Math.random() * 10);
const randomY = -5 + Math.round(Math.random() * 10);
const randomZ = -5 + Math.round(Math.random() * 10);
points.push(new THREE.Vector3(randomX, randomY, randomZ));
}
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: false });
points.forEach(function (point) {
const spGeom = new THREE.SphereGeometry(0.04);
const spMesh = new THREE.Mesh(spGeom, material);
spMesh.position.copy(point);
spGroup.add(spMesh);
});
return {
spGroup,
points
};
}
正如您在这段代码片段中看到的,我们创建了20个随机点(THREE.Vector3),并将它们推入数组中。
接下来,我们遍历此数组并创建THREE.SphereGeometry,
其位置设置为这些点之一(position.copy(point))。
所有点都添加到一个组中,这样我们就可以轻松地替换它们一旦进行重绘。
一旦您拥有这组点,从中创建THREE.ConvexGeometry就非常容易,如下面的代码片段所示:
const convexGeometry = new THREE.ConvexGeometry(points);
THREE.ConvexGeometry接受的唯一参数是包含顶点(THREE.Vector3类型)的数组。
请注意,如果要渲染光滑的THREE.ConvexGeometry,
应该调用computeVertexNormals,
正如我们在第2章《构成Three.js应用程序的基本组件》中解释的那样。
接下来的复杂几何体是THREE.LatheGeometry,例如,可以用来创建花瓶形状。
THREE.LatheGeometry
THREE.LatheGeometry允许您从一组形成曲线的点中创建形状。
如果您查看图6.2,您将看到我们创建了一些点(红点),
Three.js使用这些点创建THREE.LatheGeometry。
再次,理解THREE.LatheGeometry的外观最简单的方法是查看示例。
此几何体显示在lathe-geometry.html中。以下是从示例中截取的屏幕截图,
显示了这个几何体:
在上述截图中 ,您可以看到用于创建此几何体的点,它们显示为一组小红色球体。
这些点的位置与THREE.LatheGeometry一起传递,以及定义几何体形状的参数。
在查看所有参数之前,让我们先看看用于创建单个点以及THREE.LatheGeometry如何使用这些点的代码:
const generatePoints = () => {
// ...
const points = [];
const height = 0.4;
const count = 25;
for (let i = 0; i < count; i++) {
points.push(new THREE.Vector3((Math.sin(i * 0.4) + Math.cos(i * 0.4)) * height + 3, i / 6, 0));
}
// ...
}
// 使用相同的点创建LatheGeometry
const latheGeometry = new THREE.LatheGeometry(points, segments, phiStart, phiLength);
latheMesh = createMesh(latheGeometry);
scene.add(latheMesh);
在这段JavaScript中,我们可以看到我们生成了25个点,
其x坐标基于正弦和余弦函数的组合,而y坐标基于i和count变量。
这样创建了在上述截图中以红点可视化的样条。
基于这些点,我们可以创建THREE.LatheGeometry。
除了顶点数组外,THREE.LatheGeometry还接受其他一些参数。
以下列表解释了这些属性:
points:这些是用于生成钟/花瓶形状的样条的点。segments:创建形状时使用的段数。此数值越高,生成的形状就越圆润和平滑。这的默认值为12。phiStart:这决定了生成形状时在圆上的起始位置。这可以在0到2*PI之间取值。默认值为0。phiLength:这定义了形状生成的完整程度。例如,四分之一形状将是0.5PI。默认值为完整的360度或2PI。此形状将从phiStart属性的位置开始。
在第5章中,我们已经看到了BoxGeometry。Three.js还提供了另外两个类似于盒子的几何体,
我们将在下面讨论。
BoxLineGeometry
如果您只想显示轮廓,可以使用THREE.BoxLineGeometry。
此几何体的工作方式与THREE.BoxGeometry完全相同,但它不是渲染实心物体,
而是使用线条渲染盒子(来自box-line-geometry.html):
您可以以与THREE.BoxGeometry相同的方式使用此几何体,
但是与创建THREE.Mesh不同,我们需 要创建THREE.LineSegments,
使用可用的线条特定材质之一:
import { BoxLineGeometry } from 'three/examples/jsm/geometries/BoxLineGeometry'
const material = new THREE.LineBasicMaterial({ color: 0x000000 });
const geometry = new BoxLineGeometry(width, height, depth, widthSegments, heightSegments, depthSegments);
const lines = new THREE.LineSegments(geometry, material);
scene.add(lines);
有关可以传递到此几何体的属性的解释,请参阅第5章的THREE.BoxGeometry部分。
Three.js还提供了略微更高级的THREE.BoxGeometry,其中可以具有漂亮的圆角。
您可以使用RoundedBoxGeometry实现这一点。
THREE.RoundedBoxGeometry
这个几何体使用与THREE.BoxGeometry相同的属性,但它还允许您指定角落的圆角程度。
在rounded-box-geometry示例中,您可以看到它的外观:
对于这个几何体,我们可以通过指定width、height和depth来指定盒子的尺寸。
除了这些属性,此几何体提供了另外两个:
radius(半径):这是圆角的大小。该值越高,角落就越圆。segments(段数):此属性定义角落的详细程度。 如果将其设置为较低的值,Three.js将对角落的定义使用较少的顶点。
在继续展示如何从2D对象创建3D几何体之前,我们将看看Three.js提供的最后一个几何体,TeapotGeometry。
TeapotGeometry
TeapotGeometry是一个用于渲染茶壶的几何体,这可能并不令人惊讶。
这个茶壶是3D渲染的标准参考模型,自1975年以来一直被使用。
有关此模型的历史信息,请参阅此处:https://www.computerhistory.org/revolution/computer-graphics-music-and-art/15/206。
使用此模型的方式与迄今为止我们所见的所有其他模型完全相同:
import { TeapotGeometry } from 'three/examples/jsm/geometries/TeapotGeometry'
// ...
const geom = new TeapotGeometry(size, segments, bottom, lid, body, fitLid, blinn)
您指定特定的属性,然后创建几何体,将其分配给THREE.Mesh。根据属性的不同,结果看起来像这样(在teapot-geometry.html示例中):
要配置此几何体,您可以使用以下属性:
size(大小):这是茶壶的大小。segments(段数):这定义了用于创建茶壶线框的段数。使用的段数越多,茶壶看起来越平滑。bottom(底部):如果设置为true,则将呈现茶壶的底部。如果为false,则不呈现底部,这在茶壶位于表面上且无需呈现底部时可能会使用。lid(盖子):如果设置为true,则呈现茶壶的盖子。如果为false,则不呈现盖子。body(主体):如果设置为true,则呈现茶壶的主体。如果为false,则不呈现主体。fitLid(适应盖子):如果设置为true,则盖子将完全适应茶壶。如果为false,则盖子与茶壶的主体之间会有一小段空间。blinn(布林):这定义了是否使用与1975年原始模型相同的茶壶纵横比。
在接下来的几节中,我们将通过从2D形状中提取3D几何体的方式来查看创建几何体的另一种选择。