2016-01-23 51 views
4

this問題,我試圖生成UV映射編程與three.js所對於某些型號產品簡單的UV貼圖,我需要這個,因爲正在生成我的模型編程也和我需要申請一個簡單的紋理給他們。我已閱讀here併成功爲某些簡單的3D文本生成了UV貼圖,但將相同的貼圖應用於更復雜的模型時,它不起作用。編程方式生成模型

我嘗試應用的質地是這樣的:

enter image description here

黑色背景它的PNG圖像在短短透明。我需要將它應用於我的模型,這只是一個閃光的效果,所以我不在乎模型中的確切位置,是否有任何方法以編程方式爲這些情況創建簡單的UV貼圖?

我使用的是從鏈接的問題,這對於平面模型的偉大工程,但對於非平面模型不起作用此代碼:

assignUVs = function(geometry){ 

    geometry.computeBoundingBox(); 

    var max  = geometry.boundingBox.max; 
    var min  = geometry.boundingBox.min; 

    var offset = new THREE.Vector2(0 - min.x, 0 - min.y); 
    var range = new THREE.Vector2(max.x - min.x, max.y - min.y); 

    geometry.faceVertexUvs[0] = []; 
    var faces = geometry.faces; 

    for (i = 0; i < geometry.faces.length ; i++) { 

     var v1 = geometry.vertices[faces[i].a]; 
     var v2 = geometry.vertices[faces[i].b]; 
     var v3 = geometry.vertices[faces[i].c]; 

     geometry.faceVertexUvs[0].push([ 
     new THREE.Vector2((v1.x + offset.x)/range.x , (v1.y + offset.y)/range.y), 
     new THREE.Vector2((v2.x + offset.x)/range.x , (v2.y + offset.y)/range.y), 
     new THREE.Vector2((v3.x + offset.x)/range.x , (v3.y + offset.y)/range.y) 
     ]); 

    } 

    geometry.uvsNeedUpdate = true; 

} 
+0

如果它只是一個閃光的效果,創建一個着色器會更好嗎?像[THIS](http://blog.2pha.com/demos/threejs/shaders/voronoi_point_lights.html) – 2pha

回答

4

你需要更具體。在這裏,我將以編程方式應用UV貼圖

for (i = 0; i < geometry.faces.length ; i++) { 
    geometry.faceVertexUvs[0].push([ 
    new THREE.Vector2(0, 0), 
    new THREE.Vector2(0, 0), 
    new THREE.Vector2(0, 0), 
    ]); 
} 

快樂嗎?

有一種應用UV座標的無限方式。這個怎麼樣

for (i = 0; i < geometry.faces.length ; i++) { 
    geometry.faceVertexUvs[0].push([ 
    new THREE.Vector2(Math.random(), Math.random()), 
    new THREE.Vector2(Math.random(), Math.random()), 
    new THREE.Vector2(Math.random(), Math.random()), 
    ]); 
} 

有沒有RIGHT答案。只有你想做的事取決於你。這有點像問我如何在紙上塗鉛筆。

對不起,如此尖銳,只是指出這個問題在某種意義上是荒謬的。

無論如何,應用紋理有幾種常用方法。

  • 球面映射

    想象一下你的模型是半透明的,裏面有由膜和球內的球體是點光源,使其項目(如電影放映機)來自四面八方的球。所以,你的這種情況

    做數學與計算機正確的烏布蘇要獲得有球點由世界矩陣的逆乘以你的分球,然後恢復正常的結果。之後,雖然仍然存在紋理本身如何映射到虛擬球體的問題,但它仍然有無數的方法。

    最簡單的方法是我猜叫mercator projection這是世界的工作如何大多數2D地圖。他們有這樣的問題,即北極和南極浪費了大量空間。假設x,y,z是在前面的段落中提到的歸一化座標,然後

    U = Math.atan2(z, x)/Math.PI * 0.5 - 0.5; 
    V = 0.5 - Math.asin(y)/Math.PI; 
    
  • 投影映射

    這就像一部電影。你從一個點投射出一個二維圖像。想象一下,您在椅子上指着一臺電影放映機(或投影電視)。計算這些點

    計算這些點就像從幾乎所有WebGL應用程序所做的3D數據計算2D圖像一樣。通常他們在其頂點着色器中有這樣一行

    gl_Position = matrix * position; 
    

    其中matrix = worldViewProjection。你可以做

    clipSpace = gl_Position.xy/gl_Position.w 
    

    你現在有x,y值從-1到+1。然後,您 將它們轉換爲0到1的UV COORDS

    uv = clipSpace * 0.5 + 0.5; 
    

    當然,通常你會計算UV座標在JavaScript的初始化時間,但概念是相同。

  • 平面映射

    這是幾乎相同,只是想象中的投影儀投影映射,而不是作爲一個點,是同樣大小,只要你想突出它。換句話說,當您將模型靠近投影機時,通過投影映射,投影的圖像會變得更小,但與平面不同。

    遵循投影映射示例,這裏唯一的區別是使用正投影而不是透視投影。

  • 多維數據集映射?

    這是6個方向的有效平面映射。這取決於你 決定哪些UV座標獲得6個平面中的哪一個。我猜你大多數時候都會看到三角形的法線,看看它最面對哪個平面,然後從該平面進行平面映射。

    其實我可能會混淆我的條款。你也可以做 真正的立方體貼圖,你有一個立方體紋理,但這需要 U,V,W而不是U,V。爲此,它與球體 示例相同,除非您直接使用標準化座標作爲 U,V,W。

  • 圓柱映射

    此相似,但假設有微小的缸筒凸出到您的球體模型的映射。與球體不同,圓柱體具有方向性,但基本上可以將模型中的點移動到圓柱體的方向,然後假設x,y,z現在相對於圓柱體(換句話說,您將它們乘以矩陣的逆矩陣代表圓柱體的方向),那麼。

    U = Math.atan2(x, z)/Math.PI * 0.5 + 0.5 
    V = y 
    

2個解決方案

  1. 也許你想環境貼圖?

    Here's 1 exampleHere's another

  2. 也許你應該考慮使用像Maya或Blender這樣的建模軟件包,內置UV editors和UV投影儀。