2016-08-24 11 views
2

私は、約4百万の頂点を持つ大きなバッファジオメトリを持っており、小さなシェーディングエリアを更新する必要があります。私は現在、ランダムにvertexNormalsを更新していますが、それは遅れを引き起こします。私はジオメトリ(How to quickly update a large BufferGeometry?) のupdateRange.offsetを使ってみましたが、ソースコードを調べてみると、これがvertexNormals()関数に影響するとは思いません。THREE JS computeVertexNormals()performance

ループくれ千回:

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を実行しようとしますか?私はそれからそれを取り除くことができましたが、atleast wouldntはずっと遅れを見るでしょうか? IllにcomputeVertexNormals({offset:Int、range:int})を機能リクエストとしてGitに送信する – LrakWortep

答えて

0

BufferGeometryは、属性のサブ範囲の更新をサポートしています。これには、法線が含まれています。

BufferGeometry.computeVertexNormals()は、索引付けおよび非索引付けの両方のジオメトリをサポートします。インデックス付きジオメトリは共有頂点をサポートしているため、適切な結果を得るためには、インデックス範囲外の面が計算に含まれている必要があります。