Javascript 三个JS computeVertexNormals()性能

Javascript 三个JS computeVertexNormals()性能,javascript,three.js,Javascript,Three.js,我有一个大的缓冲区几何体,大约400万个顶点,需要更新一小块阴影区域。我目前随机更新顶点法线,但这会导致延迟。我已尝试使用几何体()的updateRange.offset 但是查看源代码,我认为这不会影响vertexNormals()函数 循环我1000次: GRID.geometry.attributes.position.array[ (array_position + 2) ] = _position[2] - WEBGLzTranslate ; GRID.geometry.attr

我有一个大的缓冲区几何体,大约400万个顶点,需要更新一小块阴影区域。我目前随机更新顶点法线,但这会导致延迟。我已尝试使用几何体()的updateRange.offset 但是查看源代码,我认为这不会影响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');
}
if(minArrayPosition.99)
{
GRID.geometry.computeFaceNormals();
GRID.geometry.computeVertexNormals();
log(“更新阴影”);
}
我想,理想情况下,我希望对顶点法线进行范围处理。也许在这里的某个地方(BufferGeometry.js:657):

if(attributes.position){
变量位置=attributes.position.array;
如果(attributes.normal==未定义){
this.addAttribute('normal',new BufferAttribute(new Float32Array(positions.length),3));
}否则{
//将现有法线重置为零
var数组=attributes.normal.array;
对于(var i=0,il=array.length;i

我应该改为研究变形材质吗?多谢了,BufferGeometry已经支持更新属性的一个子范围——包括法线

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

  • 西兰利

听起来您需要编写自己的
computeVertexNormals()
实现,它确实遵循您设置的限制。冻结是因为在当前函数完成处理或等待事件之前,JavaScript无法执行任何其他操作。长的计算循环将“冻结”浏览器的整个持续时间。可能尝试在设置的间隔函数中异步运行computeVertexNormals,该函数在运行一次后会自动终止?然后我可以将其隔开,但至少不会看到太多的延迟?我将向Git提交computeVertexNormals({offset:Int,range:Int})作为功能请求
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;

                }

            }