2014-11-21 69 views
1

我通過向新的THREE.Geometry()添加頂點和麪以創建自定義網格,然後在其上運行computeFaceNormals()和computeVertexNormals()以平滑渲染(I使用MeshPhongMaterial)。如果沒有computevertexnormals,我的網格部分會出現條紋。問題是r69中包含的computeVertexNormals()忽略了尖銳的邊緣。這是一個優雅的函數,通過平均周圍的面來構建每個頂點的法線。但是它平均了我需要保持邊緣清晰的邊緣的法線。另外一些有希望的評論question with the same topic但是沒有發佈代碼來解決邊緣尖銳問題。three.js在平滑着色時保持摺痕定製幾何

我試圖修改computeVertexNormals()來添加邊緣檢測,但沒有運氣。我的嘗試是基於檢測相鄰面之間的角度,並且只在給定閾值內時纔將它們的法線添加到平均值。這裏是我的代碼:

function computeVertexNormals(object, angle_threshold, areaWeighted) { //will compute normals if faces diverge less than given angle (in degrees) 

var v, vl, f, fl, face, vertices; 

angle = angle_threshold * 0.0174532925; //degrees to radians 

vertices = new Array(object.vertices.length); 

for (v = 0, vl = object.vertices.length; v < vl; v ++) { 

    vertices[ v ] = new THREE.Vector3(); 

} 

if (areaWeighted && areaWeighted == true) { 

    // vertex normals weighted by triangle areas 
    // http://www.iquilezles.org/www/articles/normals/normals.htm 

    var vA, vB, vC, vD; 
    var cb = new THREE.Vector3(), ab = new THREE.Vector3(), 
     db = new THREE.Vector3(), dc = new THREE.Vector3(), bc = new THREE.Vector3(); 

    for (f = 0, fl = object.faces.length; f < fl; f ++) { 

     face = object.faces[ f ]; 

     vA = object.vertices[ face.a ]; 
     vB = object.vertices[ face.b ]; 
     vC = object.vertices[ face.c ]; 

     cb.subVectors(vC, vB); 
     ab.subVectors(vA, vB); 
     cb.cross(ab); 

     vertices[ face.a ].add(cb); 
     vertices[ face.b ].add(cb); 
     vertices[ face.c ].add(cb); 

    } 

} else { 

    for (f = 0, fl = object.faces.length; f < fl; f ++) { 

     face = object.faces[ f ]; 

      vertices[ face.a ].add(face.normal); 
      vertices[ face.b ].add(face.normal); 
      vertices[ face.c ].add(face.normal); 
    } 

} 

for (v = 0, vl = object.vertices.length; v < vl; v ++) { 

    vertices[ v ].normalize(); 

} 

for (f = 0, fl = object.faces.length; f < fl; f ++) { 

    face = object.faces[ f ]; 

    //**********my modifications are all in this last section************* 

    if(face.normal && face.normal != undefined){ 

     if(vertices[ face.a ].angleTo(face.normal) < angle_threshold){ 
      face.vertexNormals[ 0 ] = vertices[ face.a ].clone(); 
     }else{ 
      face.vertexNormals[ 0 ] = face.normal.clone(); 
     } 
     if(vertices[ face.b ].angleTo(face.normal) < angle_threshold){ 
      face.vertexNormals[ 1 ] = vertices[ face.b ].clone(); 
     }else{ 
      face.vertexNormals[ 1 ] = face.normal.clone(); 
     } 
     if(vertices[ face.c ].angleTo(face.normal) < angle_threshold){ 
      face.vertexNormals[ 2 ] = vertices[ face.c ].clone(); 
     }else{ 
      face.vertexNormals[ 2 ] = face.normal.clone(); 
     } 

    } 

} 

}

大家能否請提供摺痕檢測的策略,所以我可以有平滑的形狀與一些鋒利的邊緣? 在此先感謝!

+0

相反,考慮在構建幾何時複製硬邊上的頂點。 – WestLangley 2014-11-21 09:48:14

回答

0

WestLangley在上面的評論中是正確的。爲了獲得我想要的銳利邊緣,我只是在構建幾何圖形時複製了「摺痕」上的頂點。然後我使用了THREE.Geometry()原型中包含的標準computeVertexNormals()函數。

我用一個自制的'loft'函數構造我的幾何:基本上遍歷一組形狀(使用i)並在其頂點之間創建B樣條(使用j),然後從B構造一個網格-Splines。解決的辦法是測試每個形狀的每個頂點的角度。如果它的角度大於給定的閾值(我使用了70度),我再次添加了B樣條曲線,實際上覆制了頂點。對不起,如果下面的代碼是有點神祕的背景。

    //test if vertex is on a crease 
       if (j == 0) { 
        before = arrCurves[i].vertices[j].clone().sub(arrCurves[i].vertices[arrCurves[i].vertices.length-1]); 
       }else{ 
        before = arrCurves[i].vertices[j].clone().sub(arrCurves[i].vertices[j-1]); 
       } 

       if (j == arrCurves[i].vertices.length-1) { 
        after = arrCurves[i].vertices[0].clone().sub(arrCurves[i].vertices[j]); 
       }else{ 
        after = arrCurves[i].vertices[j+1].clone().sub(arrCurves[i].vertices[j]); 
       } 

       if(before.angleTo(after) > crease_threshold){ 
        //here's where I'm adding the curve for a second time to make the 'crease' 
        arrSplines.push(new THREE.SplineCurve3(nurbsCurve.getPoints(resolution))); 
       } 

工程就像一個魅力,謝謝WestLangley!

+0

我從我在這裏找到的答案(主要是WestLangley)和他的一個直接答案中瞭解到,複製邊緣是解決問題的關鍵。我認爲我成功地複製了邊緣並基於這些邊緣繪製了新的面部。以這種方式構建的立方體(和IndexedFaceSet)看起來仍然完全平滑。然而,內置的多維數據集或框幾何看起來完全相同。我期望內置的幾何圖形可以在合理的情況下以銳利的邊緣進行渲染。我很困惑,他們不是。 – 2017-01-31 21:54:48