其他分享
首页 > 其他分享> > Babylonjs 在场景中优化处于实体墙后面的大量模型

Babylonjs 在场景中优化处于实体墙后面的大量模型

作者:互联网

Babylonjs 的摄像机转向时,如果镜头内有一面墙,墙不透明,墙后面一堆资源,比如花草树木无数个,会掉帧严重。

这时候镜头内虽然看着只有墙,但是BJS的引擎把墙后面的模型也渲染了。

例如墙后面有1000个球体,那么就可以隐藏这些球体模型。(表示1000个不同模型,否则同模型可用instance优化)

先说总结,可以使用AssetContainer进行资源管理,removeAllFromScene后,场景内totals总模型数量就下降了,帧率就提高。

测试用例截图和分析如下:

1.墙后面有1000个球,顶视图“看不到”这些球,但是绝对帧率和前视图一样,只有118帧率。

inspector也提示active meshes为1002,说明镜头内所有模型都被渲染了,无论是否只看到一面墙。

 

2.如果镜头内的1000个球体模型不加载,那么帧率可高达5800帧,所以目的为通过隐藏墙后“看不到”的模型,提高帧率。

 

3.隐藏模型方法 :mesh.isVisible = false,帧率1300,有成效,但是距离5800还太远,说明引擎是通过计算后渲染这些模型消失的。

 

4.隐藏方法:mesh.renderingGroupId=10,判断和camera的renderingGroupId交集,交集为0就在镜头内隐藏模型(具体使用方法可以查阅sandbox的inspector讲解)

但是帧率580左右,越优化越卡,说明计算每个模型的交集值太耗费内存资源了。

5. 隐藏方法:babylon有自己计算遮罩查询的方法occlusionQuery,用于判断模型边框是否镜头内(具体使用方法查阅官方API文档)

顶视图110帧,前视图45帧,引擎计算量更大了,每个模型都计算边框值,负优化。

 

6.隐藏方法:setEnable(fals),模型在inspector中可以勾选enable选项,用这个方法可以隐藏模型,

效果为3000帧,如图当前活动的模型只有2个,总模型1002个,隐藏的模型就没有被渲染,但是还处于场景计算内。

 

7. 隐藏方法:container.removeAllFromScene(),可以看到帧率5400,总模型和活动模型都为2,

所以可以通过AssetContainer管理模型,远处或者隔壁房间看不见、不需要的模型就从场景移除

 

测试排行榜  

  1. removeAllFromScene() FPS 5600
    – only two sphere FPS 5200
  2. setEnabled FPS 3000
  3. isVisible FPS 1350
  4. renderingGroupId FPS 570
  5. default show FPS 120
  6. occlusionQuery FPS 110~45 (will be used together with AssetContainer )

我的电脑 2600x+1660ti

 

测试代码 https://playground.babylonjs.com/#IC6IRV#2

var createScene = function () {


        var scene = new BABYLON.Scene(this.engine);
        var camera = new BABYLON.ArcRotateCamera('Camera', 0, 0, 10, null, scene);
        camera.minZ = 0.01;
        camera.setTarget(BABYLON.Vector3.Zero());
        camera.attachControl(canvas, false);
        var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), scene);

        
 
        var sharedGeometry = BABYLON.MeshBuilder.CreateSphere('sphere', {
            segments: 64, 
            diameter: 0.8
        }, scene).geometry;
    
        var gridSize = 10;//10x10x10
        var meshList = [];

        var ground = BABYLON.Mesh.CreateGround('ground1', gridSize * 1.5, gridSize * 1.5, 2, scene);
        ground.position.y = gridSize / 2;

var container = new BABYLON.AssetContainer(scene);


        for (var x = 0; x < gridSize; x++)
            for (var y = 0; y < gridSize; y++)
                for (var z = 0; z < gridSize; z++) {
                    // var mesh = BABYLON.MeshBuilder.CreateSphere('sphere '+ x + '_' + y + '_' + z, {
                    //     segments: 64, 
                    //     diameter: 0.8
                    // }, scene);

                    var mesh = new BABYLON.Mesh('sphere '+ x + '_' + y + '_' + z, scene);
                    sharedGeometry.applyToMesh(mesh);
                    mesh.position.set(-gridSize / 2 + x, -gridSize / 2 + y, -gridSize / 2 + z);
                   
                    
                        // mesh.occlusionQueryAlgorithmType = BABYLON.AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE;
                        // mesh.occlusionType = BABYLON.AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC;
                        // mesh.occlusionRetryCount = -1;
                        // mesh.isOccluded = true;
                 
                    // mesh.isVisible = false;      //FPS 1670
                    // mesh.renderingGroupId = 10;  //FPS 620
                    // mesh.freezeWorldMatrix();    //FPS 124
                    // mesh.setEnabled(false);      //FPS 3000

                    // gridSize==1 FPS 4500
                    //default absolute FPS 121

                    container.meshes.push(mesh)     //FPS 4500

                    meshList.push(mesh);
            
                }

 container.removeAllFromScene()
       
        // oom crash
        // var mergeMesh = BABYLON.Mesh.MergeMeshes(meshList, true, true, undefined, false, true);

        camera.setPosition(new BABYLON.Vector3(gridSize, gridSize, gridSize));
        scene.registerBeforeRender(() => {

        });

    return scene;

};

善用Playground,可以查inspector,也可以根据代码查别人写过的用例

 

 

 

 

标签:实体墙,场景,模型,Babylonjs,mesh,FPS,var,gridSize,BABYLON
来源: https://blog.csdn.net/maki077/article/details/110847109