点和精灵
在前面的章节中,我们讨论了Three.js提供的最重要的概念、对象和API。
在这一章中,我们将深入研究直到现在为止我们跳过的唯一概念:点和精灵。
通过THREE.Points(有时也称为精灵),
可以很容易地创建许多始终朝向摄像机的小矩形,
您可以使用它们来模拟雨、雪、烟等有趣的效果。
例如,您可以将单个几何体渲染为一组点,并分别控制这些点。
在本章中,我们将探讨Three.js提供的各种与点和精灵相关的功能。
更具体地说,在本章中,我们将讨论以下主题:
- 使用
THREE.SpriteMaterial和THREE.PointsMaterial创建和样式化粒子 - 使用
THREE.Points创建一组点 - 使用画布分别为每个点设置样式
- 使用纹理为单个点设置样式
- 动画
THREE.Points对象 - 从现有几何体创建
THREE.Points对象
在本章中使用的一些名称的简要说明
在较新的Three.js版本中,与点相关的对象的名称已经多次更改。
THREE.Points对象以前的名称是THREE.PointCloud,
在更旧的版本中它被称为THREE.ParticleSystem。
THREE.Sprite以前被称为THREE.Particle,而材质也经历了几次更名。
因此,如果您看到在线示例使用这些旧名称,请记住它们谈论的是相 同的概念。
让我们开始探讨粒子是什么以及如何创建它。
理解点和精灵
和大多数新概念一样,我们将从一个例子开始。
在本章的源代码中,您将找到一个名为sprite.html的例子。
打开此示例时,您将看到一个极简的场景,包含一个简单的彩色正方形:
您可以使用鼠标在此场景中旋转。 您将注意到的一点是,无论您如何查看正方形,它始终看起来相同。 例如,以下截图显示了从不同位置查看相同场景的视图:
如您所见,精灵仍然朝向摄像机倾斜,您无法查看其背后。 您可以将精灵视为始终朝向摄像机的二维平面。 如果创建一个没有任何属性的精灵,它们将呈现为小的白色二维正方形。 要创建精灵,我们只需要提供一个材质:
const material = new THREE.SpriteMaterial({ size: 0.1, color: 0xff0000 })
const sprite = new THREE.Sprite(material)
sprite.position.copy(new THREE.Vector3(1, 1, 1))
您可以使用THREE.SpriteMaterial配置精灵的外观:
color:这是精灵的颜色。默认颜色为白色。sizeAttenuation:如果设置为false,精灵的大小将不受其离摄像机的位置影响。如果设置为true,大小将基于与摄像机的距离。默认值为true。请注意,仅在使用THREE.PerspectiveCamera时,此选项才起作用。对于THREE.OrthographicCamera,它始终表现得像false。map:使用此属性,您可以将纹理应用于精灵。您可以使它们看起来像雪花,例如。此属性未在此示例中显示,但将在本章后面的使用纹理样式化粒子部分中解释。opacity:与transparent属性一起,设置精灵的不透明度。默认值为1(完全不透明)。transparent:如果设置为true,则将使用由opacity属性设置的精灵的不透明度进行渲染。默认值为false。blending:在渲染精灵时使用的混合模式。
请注意,THREE.SpriteMaterial扩展自基本的THREE.Material对象,
因此该对象的所有属性也可用于THREE.SpriteMaterial。
在继续研究更有趣的THREE.Points对象之前
,让我们更仔细地查看THREE.Sprite对象。
THREE.Sprite对象与THREE.Mesh一样扩展自THREE.Object3D对象。
这意味着您可以在THREE.Sprite上使用大多数从THREE.Mesh了解的属性和函数。
您可以使用position属性设置其位置,使用scale属性缩放它,
并使用translate属性沿其轴移动它。
使用THREE.Sprite,您可以很容易地创建一组对象并在场景中移动它们。
当您使用少量对象时,这很有效,但是当您想要使用大量THREE.Sprite对象时,
您很快就会遇到性能问题。这是因为每个对象都需要被Three.js单独管理。
Three.js提供了使用THREE.Points对象处理大量精灵的替代方法。
使用THREE.Points,Three.js不必单独管理许多个体的THREE.Sprite对象,
而只需管理THREE.Points实例。
这将使Three.js能够优化如何绘制精灵,并将导致更好的性能。
以下截图显示了使用THREE.Points对象渲染的几个精灵:
要创建THREE.Points对象,我们需要为其提供THREE.BufferGeometry。
对于前面的截图,我们可以这样创建THREE.BufferGeometry:
const createPoints = () => {
const points = []
for (let x = -15; x < 15; x++) {
for (let y = -10; y < 10; y++) {
let point = new THREE.Vector3(x / 4, y / 4, 0)
points.push(point)
}
}
const colors = new Float32Array(points.length * 3)
points.forEach((e, i) => {
const c = new THREE.Color(Math.random() * 0xffffff)
colors[i * 3] = c.r
colors[i * 3 + 1] = c.g
colors[i * 3 + 2] = c.b
})
const geom = new THREE.BufferGeometry().setFromPoints(points)
geom.setAttribute('color', new THREE.BufferAttribute(colors, 3, true))
return geom
}
const material = new THREE.PointsMaterial({ size: 0.1, vertexColors: true, color: 0xffffff })
const points = new THREE.Points(createPoints(), material)
如您从此代码片段中看到的,
首先,我们创建了一个THREE.Vector3对象数组 - 为我们想要创建精灵的每个位置一个。
此外,我们在THREE.BufferGeometry上设置了color属性,用于为每个精灵着色。
使用THREE.BufferGeometry和THREE.PointsMaterial的实例,
我们可以创建THREE.Points对象。
THREE.PointsMaterial的属性基本上与THREE.SpriteMaterial的属性相同:
color:这是点的颜色。默认颜色为0xffffff。sizeAttenuation:如果设置为false,所有点的大小将相同,无论它们离摄像机有多远。如果设置为true,大小将基于与摄像机的距离。默认值为true。map:使用此属性,您可以将纹理应用于点。您可以使它们看起来像雪花,例如。此属性未在此示例中显示,但将在本章后面的使用纹理样式化粒子部分中解释。opacity:与transparent属性一起,设置精灵的不透明度。默认值为1(完全不透明)。transparent:如果设置为true,则将使用由opacity属性设置的精灵的不透明度进行渲染。默认值为false。blending:在渲染精灵时使用的混合模式。vertexColors:通常,THREE.Points中的所有点具有相同的颜色。如果将此属性设置为true,并且在几何上已经设置了颜色的缓冲属性,则每个点将从该数组中获取颜色。默认值为false。
与往常一样,您可以使用每个示例右侧的菜单调整这些属性。 到目前为止,我们只渲染了粒子作为小正方形,这是默认行为。 然而,有两种额外的方式可以样式化粒子,我们将在下一节中展示。
使用纹理样式化粒子
在本节中,我们将讨论改变精灵外观的两种方式:
- 使用HTML画布绘制图像并为每个精灵显示
- 加载外部图像文件以定义每个精灵的外观
让我们首先自己绘制图像。