在这里列出Babylon.js官方性能优化文档的中英文对照,并在CardSimulate项目里对其中的一些优化方法进行实践。
How To
如何
Optimize your scene
优化你的场景
Table of contents 内容列表
- How To Optimize Your Scene 如何优化你的场景
- Use TransformNode instead of AbstractMesh or empty meshes 使用变换节点代替抽象网格或者空网格
- Changing per mesh culling strategy改变每个网格的剔除策略
- Reducing Shaders Overhead降低着色器开销
- Reducing World Matrices Computation 减少世界矩阵计算
- Freezing the active meshes 冻结活动的网格
- Reducing draw calls 减少绘制调用
- Reducing calls to gl.clear() 减少gl.clear()的调用
- Using depth pre-pass 使用深度预加载
- Using unindexed meshes 使用未索引的网格
- Turning AdaptToDeviceRatio Off 关闭适应设备比例(ratio是比例,rate是速率)
- Blocking the dirty mechanism 停止不好的机制
- Using Animation Ratio 使用动画比率
- Handling WebGL context lost 处理WebGL上下文丢失
- Scene with large number of meshes 处理包含大量网格的场景
- Instrumentation 仪表
- EngineInstrumentation 引擎仪表
- SceneInstrumentation 场景仪表
- Further Reading 进一步阅读
- More Advanced - L3 更进一步
How To Optimize Your Scene
如何优化你的场景
This tutorial will help you find some links and info on how you can improve your scene regarding rendering performance.
这篇教程将帮助你找到一些关于如何提升你的场景的渲染效果的链接和信息
Use TransformNode instead of AbstractMesh or empty meshes
使用变换节点代替抽象网格或者空网格
If you need node containers or transform nodes, do not use meshes but TransformNode instead. Use meshes only when associated with content to render.
如果你需要节点容器或者变换节点,不要使用网格,而是使用变换节点来替代。只在有关联的内容需要绘制时使用网格。
The meshes need to go through an evaluation process where the camera checks if they are in the frustum. This is an expensive process so reducing the number of candidates by using TransformNode when possible is a good practice.
网格需要经过一个验证流程,在这个流程中相机将检查这些网格是否在视截椎体内部。这是一个性能消耗较大的流程,所以在可能时通过使用变换节点减少这种计算的数量是一个好的实践。
(使用后1366*720分辨率fps似从20提升到22~24)
Changing per mesh culling strategy
改变每个网格的剔除策略
Starting with Babylon.js v3.3, you can now specify a strategy used to cull a specific mesh with mesh.cullingStrategy
.
从Babylon.js v3.3开始,你可以设定一个策略来剔除一个特定的网格,通过设置mesh.cullingStrategy
You can set it to:
你可以将它设置为:
BABYLON.AbstractMesh.CULLINGSTRATEGY_STANDARD
: This is the default value and it will use a combination of bounding sphere culling, bounding box culling and then frustum culling
这是默认值,它将结合使用边界球剔除和边界盒剔除,然后是截锥体剔除。
BABYLON.AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY
: This strategy will use a bounding sphere culling and then frustum culling. This is faster than the standard one but can imply having more meshes sent to the GPU. Really useful if you are CPU bound.
这个策略将使用边界球剔除,然后是截锥体剔除。这种策略比基础的版本更加快速,但是可能引起更多的网格被发送到GPU。如果你的CPU资源有限,这种方法会很有用。(把更多工作分给显卡做,但是我的CPU和GPU都不富裕啊)
Reducing Shaders Overhead
降低着色器开销
Babylon.js uses an advanced and automatic shaders engine. This system will keep shaders up to date regarding material options. If you are using a static material (ie. an immutable material) then you can let it know to Babylon.js by using the following code:
Babylon.js使用一种先进的并且自动的着色器引擎。这个系统将根据材质的选项保持着色器的更新。如果你使用的是静态材质(比如一个不变的材质)那么你可以通过以下的代码让Babylon.js知道这一点:
material.freeze();
Once frozen, the shader will remain unchanged even if you change material's properties. You will have to unfreeze it to update the inner shader:
一旦被冻结,这个着色器将保持不变,即使你改变这个材质的属性(纹理是否属于着色器??更换其他材质会不会影响??网格的isvisble会不会影响??)。你必须解冻它才能更新内部的着色器:
material.unfreeze();
(建议在完成静态材质的所有设定之后使用,不影响更换其他材质,提升到26~27
)
Reducing World Matrices Computation
减少世界矩阵计算
Every mesh has a world matrix to specify its position / rotation / scaling. This matrix is evaluated on every frame. You can improve performances by freezing this matrix. Any subsequent changes to position / rotation / scaling will then be ignore:
每个网格都有一个世界矩阵用来确定它的位置、姿态、缩放。这个矩阵在每一帧中被计算。你可以通过冻结这个矩阵来改进性能。这样任何传递(通过父元素继承?)的位置、姿态、缩放改变都将被忽略:
mesh.freezeWorldMatrix();
You can unfreeze a mesh with:
你可以使用如下代码解冻一个网格:
mesh.unfreezeWorldMatrix();
(适合用在父元素固定不变的情况下,或者提前预知哪一帧会发生改变,然后只在这一帧解冻!!!!天空盒如果设置了
infiniteDistance不应冻结世界矩阵,因为天空盒需一直移动,冻结地面之后静止帧数提升至29~30
)
Freezing the active meshes
冻结活动的网格
If you are CPU bound, you can decide to keep the list of active meshes unchanged and then free the time spent by the CPU to determine active meshes:
如果你的CPU有限,你可以考虑保持“活动网格列表”不变,这样可以节省CPU用来判断网格是否活动的时间:
scene.freezeActiveMeshes();
You can unfreeze the active meshes with:
你可以使用如下代码解冻活动网格列表
scene.unfreezeActiveMeshes();
Note that you can force a mesh to be in the active meshes before freezing the list with mesh.alwaysSelectAsActiveMesh = true
.
注意你可以在冻结活动网格列表前,强制一个网格进入活动网格列表,通过mesh.alwaysSelectAsActiveMesh = true
.
(比如isVisible==false就是非活动网格??
)
Reducing draw calls
减少绘制调用
As soon as you can please use instances as they are drawn with one single draw call.
请尽量快的用instances代替通过单独绘制调用绘制
If sharing the same material is a problem, you can then think about using clones which share the same geometry with mesh.clone("newName")
如果实例对象必须共用同一个材质对象是一个问题,你可以考虑通过语句mesh.clone("newName")
用克隆方法,克隆方法产生的mesh
共用同一个多边形对象
(instances
可以以一个网格为基础,复制出许多形状和材质相同的实例,它们的材质和多边形对象都是共用的)
Reducing calls to gl.clear()
减少gl.clear()的调用
By default, Babylon.js automatically clears the color, depth, and stencil buffers before rendering the scene. It also clears the depth and stencil buffers after switching to a new camera and before rendering a new RenderingGroup. On systems with poor fill rates, these can add up quickly and have a significant impact on performance.
默认情况下,Babylon.js会在渲染场景之前自动清空颜色、深度和模板缓存。它同样会在切换到新相机之后以及渲染一个新的渲染组之前清空深度和模板缓存。对于填充率较低的系统,这些清空操作可以被快速的汇总并且对性能有巨大的影响。
If your scene is set up in such a way that the viewport is always 100% filled with opaque geometry (if you're always inside a skybox, for instance), you can disable the default scene clearing behavior with:
如果你的场景按这种方式设定:视点一直百分之百的被不透明多边形填满(比如你一直处在一个天空盒内部),你可以用以下方法禁用默认的场景清理:
scene.autoClear =
false;
//Color
buffer
颜色缓存
scene.autoClearDepthAndStencil =
false;
//Depth
and
stencil, obviously
显然是深度和模板缓存
If you know that the geometry in a particular RenderingGroup will always be positioned in front of geometry from other groups, you can disable buffer clearing for that group with the following:
如果你确定在某个渲染组中的多边形将一直位于其他组的多边形之前,你可以禁用这个组的缓存清理,通过以下方法:
scene.setRenderingAutoClearDepthStencil(
renderingGroupIdx,
autoClear,
depth,
stencil);
autoClear
: true
to enable auto clearing. If false
, overrides depth
and stencil
为真则启动自动清理。否则,覆盖深度和模板
depth
: Defaults to true
to enable clearing of the depth buffer
默认为真启动深度缓存清理
stencil
: Defaults to true
to enable clearing of the stencil buffer
默认为真启动模板缓存清理
Go ahead and be aggressive with these settings. You'll know if it's not appropriate for your application if you see any smearing!
尽管大胆测试这些设置。如果你在你的应用中看到任何污渍你将知道这个设置是否适合。
(在场景层面执行两个方法禁用了三种缓存,暂时未发现渲染异常,静止fps增加到37~38,但是在场景中漫游一段时间后fps又降低了,但是如果要在场景中使用多重半透明材质,还需要更谨慎的测试)
Using depth pre-pass
使用深度预传递
When dealing with complex scenes, it could be useful to use depth pre-pass. This technique will render designated meshes only in the depth buffer to leverage early depth test rejection. This could be used for instance when a scene contains meshes with advanced shaders. To enable a depth pre-pass for a mesh, just call mesh.material.needDepthPrePass = true
.
在处理复杂的场景时,使用深度预传递是很有用的。这项技术将只在深度缓存中(意思是一个不显示的网格,但能影响其他网格的显示?)渲染指定的网格,来影响早期的深度测试剔除。在有网格应用了高级着色器的场景中这会很有用。要启用一个网格的深度预传递,只需要调用:mesh.material.needDepthPrePass = true
.
Using unindexed meshes
使用非索引的网格
By default Babylon.js uses indexed meshes where vertices can be reuse by faces. When vertex reuse is low and when vertex structure is fairly simple (like just a position and a normal) then you may want to unfold your vertices and stop using indices:
默认情况下Babylon.js使用索引的网格,这时顶点可以通过面来引用。当顶点引用较少或者顶点结构相当简单时(比如只有一个位置和一个法线),那么你可能想要展开你的顶点并且停止使用索引:
mesh.convertToUnIndexedMesh();
For example this works very well for a cube where it is more efficient to send 32 positions instead of 24 positions and 32 indices.
例如这种设定对于立方体非常好用,这时发送32个位置以代替24个位置和32个索引是更有效率的。
(其实是换成了OpenGL更基础的一种顶点绘制方式,给没有精确点击的网格设置这种绘制方式?也许能加快场景加载速度?但是fps反而降低了,改回索引方式后fps恢复,估计可能是非索引方式在检测pick时消耗更大)
Turning AdaptToDeviceRatio Off
关闭适应设备比例
By default, Babylon.js will adapt to device ratio in order to produce the best possible quality even on high-DPI devices.
默认情况下,Babylon.js会适应设备的比例来产生尽可能高的图像质量,即使是在高分辨率设备上。
The drawback is that this could cost a lot on low-end devices. You can turn it off with the fourth parameter of the Engine constructor:
后果是在低端设备上这将造成很大的消耗。你可以通过引擎的构造方法的第四个参数关闭它:
varengine =
newBABYLON.Engine(canvas, antialiasing,
null,
false);
In the same constructor, you may also want to turn off antialiasing support with the second parameter.
同样是在这个构造函数中,你也可能想通过第二个参数关闭抗锯齿支持。
Blocking the dirty mechanism
停止不好的机制
By default the scene will keep all materials up to date when you change a property that could potentially impact them (alpha, texture update, etc...). To do so the scene needs to go through all materials and flag them as dirty. This could be a potential bottleneck if you have a lot of material.
默认情况下,场景将在你改变任何潜在的可能影响材质的属性时更新所有的材质(透明度、纹理更新等等)。要做到这一点场景需要遍历所有的材质然后将它们标志为脏的。在你有许多材质时这可能成为一个潜在的瓶颈。
To prevent this automatic update, you can execute:
要阻止这种自动的更新,你可以执行:
scene.blockMaterialDirtyMechanism =
true;
Do not forget to restore it to false when you are done with your batch changes.
不要忘了将它恢复为false,在你需要批量更改材质时。
(使用后帧数似乎略有提高,可能和前面的材质冻结存在部分功能重合)
Using Animation Ratio
使用动画比率
Babylon.js processes speed depending on the current frame rate.
Babylon.js根据当前帧率计算速度。
On low-end devices animations or camera movement may differ from high-end devices. To compensate this you can use:
在低端设备上动画或者相机移动可能和高端设备不同。要补偿这一点你可以使用:
scene.getAnimationRatio();
The return value is higher on low frame rates.
在低帧率的情况下返回值更高
Handling WebGL context lost
处理WebGL上下文丢失
Starting with version 3.1, Babylon.js can handle WebGL context lost event. This event is raised by the browser when the GPU needs to be taken away from your code. This can happen for instance when using WebVR in hybrid scenario (with multiple GPU). In this case, Babylon.js has to recreate ALL low level resources (including textures, shaders, program, buffers, etc.). The process is entirely transparent and done under the hood by Babylon.js.
从3.1版本开始Babylon.js可以处理WebGL上下文丢失事件。这个事件由浏览器在CPU需要从你的代码上移开时触发。例如这种情况会在再混合场景中使用WebVR时发生(具有多个CPU)。在这种情况下,Babylon.js不得不重新建立所有的底层资源(包括纹理、着色器、程序、缓存等等)。这个流程是完全透明的并且由Babylon.js的底层进行。
As a developer you should not be concerned by this mechanism. However, to support this scenario, Babylon.js may need an additional amount of memory to keep track of resources creation. If you do not need to support WebGL context lost event, you can turn off the tracking by instantiating your engine with doNotHandleContextLost option set to true.
作为一个开发者你不需要了解这个机制。但是,要支持这个机制,Babylon.js可能需要一些额外的内存来追踪资源的建立。如果你不需要支持WebGL上下文丢失事件,你可以通过将引擎的doNotHandleContextLost选项设为true来关闭这个追踪。
If you created resources that need to be rebuilt (like vertex buffers or index buffers), you can use the engine.onContextLostObservable
and engine.onContextRestoredObservable
observables to keep track of the context lost and context restored events.
如果你的已经被建立的资源需要被重建(比如顶点缓存或者索引缓存),你可以使用engine.onContextLostObservable
和engine.onContextRestoredObservable
两个标志来追踪上下文丢失和上下文重建事件
(也就是说显卡要去做别的用,或者换成另一块显卡?)
Scene with large number of meshes
具有大量网格的场景
If you have a large number of meshes in a scene, and need to reduce the time spent in adding/removing thoses meshes to/from the scene, There are several options of the Scene
constructor that can help :
如果你的场景中有大量的网格,并且需要降低向这个场景中添加或者移除网格的时间消耗,场景工作函数的一些选项可能有帮助
- Setting the option
useGeometryIdsMap
totrue
will speed-up the addition and removal ofGeometry
in the scene.
将useGeometryIdsMap
选项设为true
将加速场景中几何体的添加和移除
- Setting the option
useMaterialMeshMap
totrue
will speed-up the disposing ofMaterial
by reducing the time spent to look for bound meshes.
将useMaterialMeshMap
选项设为true
将加速材质的回收,通过减少寻找绑定的网格所需的时间做到这一点。
- Setting the option
useClonedMeshMap
totrue
will speed-up the disposing ofMesh
by reducing the time spent to look for associated cloned meshes.
将useClonedMeshMap
选项设为true
将加速网格的回收,通过减少相关的被克隆网格查找时间来实现这一点。
For each of this options turned on, Babylon.js will need an additional amount of memory.
对于开启的每一个选项,Babylon.js都会需要额外的内存。(上面三种的原理和数据库通过建索引加快查询速度的原理是一样的)
Also, If you are disposing a large number of meshes in a row, you can save unecessary computation by turnning the scene property blockfreeActiveMeshesAndRenderingGroups
to true just before disposing the meshes, and set it back to false
just after, like this :
同样,如果你要在一行中回收大量的网格,你可以节省一些不必要的计算,通过在回收这些网格前将场景的blockfreeActiveMeshesAndRenderingGroups
属性(成块释放活动网格和渲染组?)设为true
,然后在回收完毕后将它恢复为false
,就像这样:
scene.blockfreeActiveMeshesAndRenderingGroups =
true;
/*
* Dispose all the meshes in a row here在这里一次性回收所有的网格
*/
scene.blockfreeActiveMeshesAndRenderingGroups =
false;
Instrumentation
指示器
Instrumentation is a key tool when you want to optimize a scene. It will help you figure out where are the bottlenecks so you will be able to optmize what needs to be optimized.
在你想要优化一个场景时,指示器是一种关键的工具。它将帮助你指出哪里是性能瓶颈,于是你可以优化需要被优化的地方。
EngineInstrumentation
引擎指示器
The EngineInstrumentation class allows you to get the following counters:
引擎指示器类允许你获取如下计数器:
- gpuFrameTimeCounter: Time (in nanoseconds) spent by the GPU to render a single frame. Must be turned on with
instrumentation.captureGPUFrameTime = true
.
GPU帧时间计数器:GPU渲染一帧所花费的时间(以纳秒表示)。需要把instrumentation.captureGPUFrameTime
属性设为true
。
- shaderCompilationTimeCounter: Time (in milliseconds) spent by the CPU to compile all shaders. Must be turned on with
instrumentation.captureShaderCompilationTime = true
.
着色器计算时间计数器:CPU计算所有着色器的时间(以毫秒表示)。必须把instrumentation.captureShaderCompilationTime
属性设为true
。
Here is an example of how to use engine instrumentation: https://www.babylonjs-playground.com/#HH8T00#1 -
这是一个如何使用引擎指示器的例子:
1 var createScene = function () { 2 var scene = new BABYLON.Scene(engine); 3 var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene); 4 var material = new BABYLON.StandardMaterial("kosh", scene); 5 var sphere1 = BABYLON.Mesh.CreateSphere("Sphere1", 32, 5, scene); 6 var light = new BABYLON.PointLight("Omni0", new BABYLON.Vector3(-17.6, 18.8, -49.9), scene); 7 8 camera.setPosition(new BABYLON.Vector3(-15, 3, 0)); 9 camera.attachControl(canvas, true); 10 11 // Sphere1 material 12 material.refractionTexture = new BABYLON.CubeTexture("/textures/TropicalSunnyDay", scene); 13 material.reflectionTexture = new BABYLON.CubeTexture("/textures/TropicalSunnyDay", scene); 14 material.diffuseColor = new BABYLON.Color3(0, 0, 0); 15 material.invertRefractionY = false; 16 material.indexOfRefraction = 0.98; 17 material.specularPower = 128; 18 sphere1.material = material; 19 20 material.refractionFresnelParameters = new BABYLON.FresnelParameters(); 21 material.refractionFresnelParameters.power = 2; 22 material.reflectionFresnelParameters = new BABYLON.FresnelParameters(); 23 material.reflectionFresnelParameters.power = 2; 24 material.reflectionFresnelParameters.leftColor = BABYLON.Color3.Black(); 25 material.reflectionFresnelParameters.rightColor = BABYLON.Color3.White(); 26 27 // Skybox 28 var skybox = BABYLON.Mesh.CreateBox("skyBox", 100.0, scene); 29 var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene); 30 skyboxMaterial.backFaceCulling = false; 31 skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("/textures/TropicalSunnyDay", scene); 32 skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE; 33 skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0); 34 skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0); 35 skyboxMaterial.disableLighting = true; 36 skybox.material = skyboxMaterial; 37 38 var colorGrading = new BABYLON.ColorGradingTexture("/textures/LateSunset.3dl", scene); 39 skyboxMaterial.cameraColorGradingTexture = colorGrading; 40 material.cameraColorGradingTexture = colorGrading; 41 skyboxMaterial.cameraColorGradingEnabled = true; 42 material.cameraColorGradingEnabled = true; 43 44 // Instrumentation初始化指示器 45 var instrumentation = new BABYLON.EngineInstrumentation(engine); 46 instrumentation.captureGPUFrameTime = true; 47 instrumentation.captureShaderCompilationTime = true; 48 49 // GUI 50 var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI"); 51 var stackPanel = new BABYLON.GUI.StackPanel(); 52 stackPanel.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP; 53 stackPanel.isVertical = true; 54 advancedTexture.addControl(stackPanel); 55 56 var text1 = new BABYLON.GUI.TextBlock(); 57 text1.text = ""; 58 text1.color = "white"; 59 text1.fontSize = 16; 60 text1.height = "30px"; 61 stackPanel.addControl(text1); 62 63 var text2 = new BABYLON.GUI.TextBlock(); 64 text2.text = ""; 65 text2.color = "white"; 66 text2.fontSize = 16; 67 text2.height = "30px"; 68 stackPanel.addControl(text2); 69 70 var text3 = new BABYLON.GUI.TextBlock(); 71 text3.text = ""; 72 text3.color = "white"; 73 text3.fontSize = 16; 74 text3.height = "30px"; 75 stackPanel.addControl(text3); 76 77 var text4 = new BABYLON.GUI.TextBlock(); 78 text4.text = ""; 79 text4.color = "white"; 80 text4.fontSize = 16; 81 text4.height = "30px"; 82 stackPanel.addControl(text4); 83 84 var text5 = new BABYLON.GUI.TextBlock(); 85 text5.text = ""; 86 text5.color = "white"; 87 text5.fontSize = 16; 88 text5.height = "30px"; 89 stackPanel.addControl(text5); 90 91 var i = 0; 92 scene.registerBeforeRender(function () { 93 colorGrading.level = Math.sin(i++ / 120) * 0.5 + 0.5; 94 //读取指示器 95 text1.text = "current frame time (GPU): " + (instrumentation.gpuFrameTimeCounter.current * 0.000001).toFixed(2) + "ms"; 96 text2.text = "average frame time (GPU): " + (instrumentation.gpuFrameTimeCounter.average * 0.000001).toFixed(2) + "ms"; 97 text3.text = "total shader compilation time: " + (instrumentation.shaderCompilationTimeCounter.total).toFixed(2) + "ms"; 98 text4.text = "average shader compilation time: " + (instrumentation.shaderCompilationTimeCounter.average).toFixed(2) + "ms"; 99 text5.text = "compiler shaders count: " + instrumentation.shaderCompilationTimeCounter.count; 100 }); 101 102 return scene; 103 }
Please note that each counter is PerfCounter object which can provide multiple properties like average, total, min, max, count, etc.
请注意每个计数器都是一个性能计数器对象,这个对象可以提供多种属性,比如平均值、合计值、最小值、最大值、计数等等。
GPU timer require a special extension (EXT_DISJOINT_TIMER_QUERY) in order to work. This extension has been disabled due to Spectre and Meltdown on all major browsers. This is still possible to use by enabling the flag gfx.webrender.debug.gpu-time-queries on firefox at the moment. This should be re-enabled soon in the browsers.
GPU计数器要起作用需要一个特殊的扩展(EXT_DISJOINT_TIMER_QUERY)。这个扩展因为幽灵与熔毁被所有的主要浏览器禁用了。但这时仍然可能通过在火狐浏览器上设置gfx.webrender.debug.gpu-time-queries标志来启用它。这一功能应该会很快在浏览器中被重新启用。
SceneInstrumentation
场景计数器
The SceneInstrumentation class allows you to get the following counters (per scene):
场景计数器类允许你获取如下的计数器(每个场景都有):
- activeMeshesEvaluationTimeCounter: Time (in milliseconds) spent to evaluable active meshes (based on active camra frustum). Must be turned on with
instrumentation.captureActiveMeshesEvaluationTime = true
.
活动网格评价时间计数器:评价活动网格(根据活动相机的截锥体)所花费的时间(用毫秒表示)。必须设置instrumentation.captureActiveMeshesEvaluationTime= true
.
- renderTargetsRenderTimeCounter: Time (in milliseconds) spent to render all render target textures. Must be turned on with
instrumentation.captureRenderTargetsRenderTime = true
.
渲染目标渲染时间计数器:渲染所有渲染目标纹理所花费的时间(毫秒)必须设置instrumentation.captureRenderTargetsRenderTime = true
.
- drawCallsCounter: Number of draw calls (actual calls to engine.draw) per frame. A good advice is to keep this number as small as possible.
绘制调用计数器:每一帧里调用绘制的次数(其实是调用engine.draw的次数)。一个忠告是保持这个数字越小越好。
- textureCollisionsCounter: Number of time a texture has to be removed to free a texture slot. Generally, there are 16 texture slots on most recent hardwares. Babylon.js will try to use all of them as the process of binding a texture is expensive. It is a good idea to try to keep this number as low as possible.
纹理冲突计数器:纹理不得不被移除来释放纹理槽位的次数。一般的,最新的硬件都有16个纹理槽位。Babylon.js会尝试使用所有的槽位,因为绑定一个纹理的过程是昂贵的。保持这个数字尽量低是一个好主意。
- frameTimeCounter: Time (in milliseconds) spent to process an entire frame (including animations, physics, render targets, special fx, etc.). Must be turned on with
instrumentation.captureFrameTime = true
.
帧时间计数器:计算一整个帧(包括动画、物理效果、渲染目标、特殊效果等等)所花费的时间(毫秒)。必须设置instrumentation.captureFrameTime = true
.
- renderTimeCounter: Time (in milliseconds) spent to render a frame. Must be turned on with
instrumentation.captureRenderTime = true
.
渲染时间计数器:渲染一帧花费的时间
- interFrameTimeCounter: Time (in milliseconds) spent between two frames. Must be turned on with
instrumentation.captureInterFrameTime = true
.
跨帧时间:两帧之间的时间
- particlesRenderTimeCounter: Time (in milliseconds) spent rendering particles (including animations). Must be turned on with
instrumentation.captureParticlesRenderTime = true
.
粒子渲染时间:渲染粒子所花费的时间(包括粒子的动画)
- spritesRenderTimeCounter: Time (in milliseconds) spent rendering sprites. Must be turned on with
instrumentation.captureSpritesRenderTime = true
.
精灵渲染时间:渲染精灵所花费的时间
- physicsTimeCounter: Time (in milliseconds) spent simulating physics. Must be turned on with
instrumentation.capturePhysicsTime = true
.
物理效果时间:进行物理模拟所花费的时间
- cameraRenderTimeCounter: Time (in milliseconds) spent to render a camera. Must be turned on with
instrumentation.captureCameraRenderTime = true
.
相机渲染时间:渲染一个相机所花费的时间
Those counters are all resetted to 0 at the beginning of each frame. Therefore it is easier to access them in the onAfterRender callback or observable.
在每一帧的开始所有这些计数器都会被重置为0.因此在onAfterRender的回调里获取它们是更容易的。
Further Reading
进一步阅读
More Advanced - L3
How to Use Scene Optimizer How To Optimize Your Scene With Octrees
如何使用场景优化器(是Babylon.js提供的一款自动优化工具,能够根据设置的策略自动将场景优化为设置的帧数)、如何使用八叉树(用来快速判断物体所在的区域,内置的物理引擎就使用了这种技术)优化你的场景
时间有限,并没有经过充分的校对与测试,如果发现错误请在评论区指出。