3

適用於高度圖SphereGeometry [編輯:看this jsfiddle for a live example plus accompanying code]在three.js所

使用three.js所我想呈現出具有突出特點的一些天體。

不幸的是,沒有提供關於如何將球面高度貼圖應用於threejs的示例,但它們確實有一個將高度圖應用於平面的示例。

我把所述實施例和修改它使用SphereGeometry();代替PlaneGeometry();

顯然球體的幾何形狀是從一個平面的臨界不同,並且呈現出的結果時,球體示出爲平坦的一塊紋理。

用於飛機的高度貼圖代碼:

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; 
} 

現在我猜的解決方法比較簡單:不是映射到平面的2D在for循環的座標,它必須找到的表面座標在3d空間中的球體。不幸的是,我不是真正的3D數學專業人員,所以我幾乎堅持在這一點上。

適用於球體和所有代碼的高度貼圖的一個示例放在this 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可以用來控制球的大小和它的高度圖。

+0

僅供參考,您可以創建內嵌代碼通過跨越與周圍的反引號代碼。這樣你就不需要一個單獨的行來作爲單個函數的名字。 –

+0

你可以展示你的實例,然後問一個具體的問題嗎? – WestLangley

回答

0

如果您想要將2D地圖應用到3D球體表面,則需要使用球體的UV。幸運的是,默認情況下,UVs會帶有THREE.SphereGeometry

儘管UVs是按面存儲的,所以您需要遍歷faces數組。

對於幾何形狀的每個面:

  • 閱讀FaceVertexUvs陣列爲每個相關聯的頂點在相應的UV值。
  • 使用該UV位置讀取高度圖值。
  • 用該值沿頂點法線移動頂點。faces數組給出了頂點索引,您可以使用該索引來索引vertices數組以獲取/設置頂點位置。

此之後全部完成,設置verticesNeedUpdatetrue更新頂點。

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/