4

[编辑:见这个 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 可用于控制球体的大小和其上的高度图。

4

2 回答 2

1

使用 vector3 移动每个顶点:

  var vector = new THREE.Vector3()
  vector.set(geometry.vertices[i].x, geometry.vertices[i].y, geometry.vertices[i].z);
  vector.setLength(h);
  geometry.vertices[i].x = vector.x;
  geometry.vertices[i].y = vector.y;
  geometry.vertices[i].z = vector.z;

示例:http: //jsfiddle.net/damienlabat/b3or4up3/

于 2016-04-28T16:01:32.553 回答
0

如果要将 2D 贴图应用到 3D 球体表面,则需要使用球体的 UV。幸运的是,默认情况下带有 UV THREE.SphereGeometry

但是,UV 是按面存储的,因此您需要遍历faces数组。

对于几何中的每个面:

  • 读取FaceVertexUvs数组中每个关联顶点的对应 UV 值。
  • 使用该 UV 位置读取高度图值。
  • 将顶点沿顶点法线移动该值。该faces数组给出了顶点索引,您可以使用它来索引vertices数组以获取/设置顶点位置。

完成后,设置verticesNeedUpdatetrue更新顶点。

于 2013-08-24T08:56:34.853 回答