2016-08-24 401 views
2

我有一個很大的緩衝區幾何圖形,大約有400萬個頂點,需要更新一個小區域的陰影。我目前隨機更新vertexNormals,但會導致延遲。我試圖使用幾何(How to quickly update a large BufferGeometry?) 的updateRange.offset,但查看源代碼我不認爲這會影響vertexNormals()函數。THREE JS computeVertexNormals()性能

循環我1000次:

GRID.geometry.attributes.position.array[ (array_position + 2) ] = _position[2] - WEBGLzTranslate ; 
GRID.geometry.attributes.color.array[ (array_position) + 0 ] = color.r; 
GRID.geometry.attributes.color.array[ (array_position) + 1 ] = color.g; 
GRID.geometry.attributes.color.array[ (array_position) + 2 ] = color.b; 

然後設置更新:

if(minArrayPosition < Infinity){ 
    GRID.geometry.attributes.position.updateRange = {}; 
    GRID.geometry.attributes.position.offset = minArrayPosition; 
    GRID.geometry.attributes.position.count = maxArrayPosition - minArrayPosition; 
    GRID.geometry.attributes.position.needsUpdate = true; 
    GRID.geometry.verticesNeedUpdate = true; 
} 

GRID.geometry.attributes.color.needsUpdate = true; 
GRID.material.needsUpdate = true; 
if(Math.random() > .99) 
{ 
    GRID.geometry.computeFaceNormals(); 
    GRID.geometry.computeVertexNormals(); 
    console.log('Updating Shadding'); 
} 

理想我想有對vertexNormals範圍內的工作,我想。也許在這裏某處(BufferGeometry.js:657):

if (attributes.position) { 

     var positions = attributes.position.array; 

     if (attributes.normal === undefined) { 

      this.addAttribute('normal', new BufferAttribute(new Float32Array(positions.length), 3)); 

     } else { 

      // reset existing normals to zero 

      var array = attributes.normal.array; 

      for (var i = 0, il = array.length; i < il; i ++) { 

       array[ i ] = 0; 

      } 

     } 

     var normals = attributes.normal.array; 

     var vA, vB, vC, 

     pA = new Vector3(), 
     pB = new Vector3(), 
     pC = new Vector3(), 

     cb = new Vector3(), 
     ab = new Vector3(); 

     // indexed elements 

     if (index) { 

      var indices = index.array; 

      if (groups.length === 0) { 

       this.addGroup(0, indices.length); 

      } 

      for (var j = 0, jl = groups.length; j < jl; ++ j) { 

       var group = groups[ j ]; 

       var start = group.start; 
       var count = group.count; 

       for (var i = start, il = start + count; i < il; i += 3) { 

        vA = indices[ i + 0 ] * 3; 
        vB = indices[ i + 1 ] * 3; 
        vC = indices[ i + 2 ] * 3; 

        pA.fromArray(positions, vA); 
        pB.fromArray(positions, vB); 
        pC.fromArray(positions, vC); 

        cb.subVectors(pC, pB); 
        ab.subVectors(pA, pB); 
        cb.cross(ab); 

        normals[ vA ] += cb.x; 
        normals[ vA + 1 ] += cb.y; 
        normals[ vA + 2 ] += cb.z; 

        normals[ vB ] += cb.x; 
        normals[ vB + 1 ] += cb.y; 
        normals[ vB + 2 ] += cb.z; 

        normals[ vC ] += cb.x; 
        normals[ vC + 1 ] += cb.y; 
        normals[ vC + 2 ] += cb.z; 

       } 

      } 

我應該看看變形材料,而不是?謝謝

+0

聽起來像是你需要編寫自己的執行'computeVertexNormals()'這不跟着你設置的限制。凍結是因爲在當前函數完成其處理或等待事件之前JavaScript不能執行任何其他操作。長的計算循環會在整個過程中「凍結」瀏覽器。 – Leeft

+0

也許嘗試運行computeVertexNormals asynch在一個設置的時間間隔函數,運行一次後殺死自己?然後,我可以把它分開,但至少不會看到滯後?提交computeVertexNormals({offset:Int,range:int})作爲功能請求 – LrakWortep

回答

0

BufferGeometry已經支持更新屬性的子範圍 - 包括法線。

BufferGeometry.computeVertexNormals()支持索引和非索引幾何。索引幾何支持共享頂點,因此可能存在索引範圍之外的面必須包含在計算中才能獲得正確的結果。