[编辑:见这个 jsfiddle 的一个活生生的例子加上随附的代码]
使用three.js,我试图渲染出一些具有突出特征的天体。
不幸的是,没有提供关于如何使用 threejs 应用球形高度图的示例,但他们确实有一个将高度图应用于平面的示例。
我举了一个例子并将其修改为使用 aSphereGeometry();
而不是 aPlaneGeometry();
显然,球体的几何形状与平面的几何形状截然不同,在渲染结果时,球体显示为平坦的纹理。
平面的高度图代码:
var plane = new THREE.PlaneGeometry( 2000, 2000, quality - 1, quality - 1 );
plane.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
for ( var i = 0, l = plane.vertices.length; i < l; i ++ ) {
var x = i % quality, y = ~~ ( i / quality );
plane.vertices[ i ].y = data[ ( x * step ) + ( y * step ) * 1024 ] * 2 - 128;
}
现在我猜测解决方案相对简单:不是在 for 循环中映射到平面的 2d 坐标,而是必须在 3d 空间中找到球体的表面坐标。不幸的是,我并不是真正的 3d 数学专家,所以我几乎被困在这一点上。
应用于球体的高度图示例和所有代码都放在这个 jsfiddle中。更新的jsfiddle显示了一个改变的球体,但使用随机数据而不是高度图数据。
我知道你可以扭曲球体的 3d 点来生成这些表面细节,但我想使用高度图来做到这一点。据我所知,这个 JSFiddle 会随机改变点以使球体呈现岩石外观,但显然看起来不太自然。
编辑:以下是我希望实现将高度图数据映射到球体所需的逻辑。
为了将数据映射到球体,我们需要将坐标从简单的球坐标系(经度 φ、纬度 θ、半径 r)映射到笛卡尔坐标(x、y、z)。就像在正常的高度映射中 (x, y) 处的数据值映射到 z 一样,我们将 (φ, θ) 处的值映射到 r。这种转变归结为:
x = r × cos φ × sin θ
y = r × sin φ × sin θ
z = r × cos θ
r = Rdefault + Rscale × d(φ, θ)
参数 Rdefault 和 Rscale 可用于控制球体的大小和其上的高度图。