ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-12-07 23:31:13  阅读:467  来源: 互联网

标签:实体墙 场景 模型 Babylonjs mesh FPS var gridSize BABYLON


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有