三个JS computeVertexNormals()性能

时间:2016-08-24 03:23:49

标签: javascript three.js

我有一个大的缓冲区几何体,大约有400万个顶点,需要更新一小部分着色。我目前随机更新vertexNormals,但它会导致延迟。我尝试使用几何的updateRange.offset(How to quickly update a large BufferGeometry?)  但是查看源代码我不认为这会影响vertexNormals()函数。

循环我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;

                }

            }

我应该研究变形材料吗?感谢

1 个答案:

答案 0 :(得分:0)

BufferGeometry已经支持更新属性的子范围 - 包括法线。

BufferGeometry.computeVertexNormals()支持索引和非索引几何。索引几何支持共享顶点,因此可能存在索引范围之外的面,必须包含在计算中才能获得正确的结果。