2

我正在创建一个带有地图的 3D 地球,它应该在几秒钟后解开并填满屏幕。

我已经设法使用 three.js 和 webGL 创建了地球,但我无法找到任何有关能够为形状变化设置动画的信息。任何人都可以提供任何帮助吗?甚至可能吗?

4

3 回答 3

6

(Abstract Algorithm 和 Kevin Reid 的答案很好,只缺少一件事:一些实际的 Three.js 代码。)

您基本上需要计算原始球体的每个点在展平成平面后将映射到的位置。该数据是着色器的一个属性:附加到每个顶点的一段数据,该数据在几何的顶点之间是不同的。然后,要对从原始位置到结束位置的过渡进行动画处理,在动画循环中,您需要更新已经过去的时间量。该数据是着色器的统一数据:一段数据在动画的每一帧期间对于所有顶点保持不变,但可能会从一帧到下一帧发生变化。最后,还有一个名为“mix”的便捷函数,它将在每个顶点的原始位置和结束/目标位置之间进行线性插值。

我为你写了两个例子:第一个只是“展平”一个球体,将点 (x,y,z) 发送到点 (x,0,z)。

http://stemkoski.github.io/Three.js/Shader-Attributes.html

第二个示例遵循抽象算法在评论中的建议:“将球体的顶点展开回平面表面,如逆球体 UV 映射。” 在这个例子中,我们可以很容易地从 UV 坐标中计算出结束位置,因此在这种情况下我们实际上不需要属性。

http://stemkoski.github.io/Three.js/Sphere-Unwrapping.html

希望这可以帮助!

于 2013-06-13T18:29:04.567 回答
1

在 3D 中,一切皆有可能。;)

你的球体几何有它自己的顶点,基本上你只需要动画它们的位置,所以在动画之后它们都坐在一个平面上。

尝试使用相同数量的顶点创建球体和平面几何体,并使用球体和平面原始值的插值动画球体的顶点。这样,一开始你会有球体形状,最后是平面形状。

希望这会有所帮助,如果您需要更多指令,请告诉我如何操作。

myGlobe.geometry.vertices[index].position = something_calculated;
// myGlobe is instance of THREE.Mesh and something_calculated would be THREE.Vector3 instance that you can calculate in some manner (sphere-plane interpolation over time)
于 2013-06-01T13:21:16.657 回答
1

(Abstract Algorithm 的回答很好,但我认为有一点需要改进:即使用顶点着色器。)

您使用地图图像制作一组顶点。然后,设计一个在球体形状和平面形状之间进行插值的计算。它不一定是线性插值 - 例如,一种可能很好的方法是将地图放在半径增加的球体的一小部分上,直到它看起来平坦(一直得到它会很棘手)。

然后,在您的顶点着色器中编写该计算。每个顶点的位置可以完全根据纹理坐标(因为它确定顶点在地图上的位置并暗示其位置)和包含时间值的统一变量来计算。

使用顶点着色器将比使用 JavaScript 重新计算和重新上传坐标更有效,允许完美流畅的动画以及大量空闲资源来做其他事情。

不幸的是,我对 Three.js 不够熟悉,无法详细描述如何做到这一点,但以上所有内容在基本的 WebGL 中都很简单,并且在任何体面的框架中都应该是可能的。

于 2013-06-01T15:53:18.677 回答