テンプレート:Release Notes/2.49/Game Engine/Optimization

提供: wiki
< テンプレート:Release Notes‎ | 2.49
2018年6月29日 (金) 03:41時点におけるYamyam (トーク | 投稿記録)による版 (1版 をインポートしました)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索

Important Optimizations

  • Speedup for bullet creating convex hull meshes for faster startup times.
  • Speedup for bullet physics mesh conversion
  • Speedup for Blender Player's profile drawing
  • Implemented a cache for the expression controller for better performance.

Minor Optimizations

  • Flat shaded faces can now share vertices's increasing performance for some models.
  • Compile scripts when converting controllers to give more predictable performance and print syntax errors early on rather then when the script is first executed.
  • Where possible use vec.setValue(x,y,z) to assign values to a vector instead of vec= MT_Vector3(x,y,z), for MT_Point and MT_Matrix types too.
  • Added SG_Spatial::SetWorldFromLocalTransform() since the local transform is use for world transform in some cases.
  • Removed some unneeded vars from UpdateChildCoordinates functions
  • Py API - Mouse, Ray, Radar sensors - use PyObjectFrom(vec) rather then filling the lists in each function. Use METH_NOARGS for get*() functions.
  • Py API - When reading python vector arguments, Check for a tuple rather then using a generic python sequencer, approx 2x speedup.
  • Speed up mesh conversion by avoiding allocation/deallocation of material object on each face.
  • Allow to create display list on meshes with modifiers but without armature and shape keys. These modified meshes are static and can be put safely in a display list. As the rendering of modifiers is done in direct openGL call, giving a bit of a performance boost.

BGE Scenegraph improvement

The scenegraph improvement consists in avoiding position update if the object has not moved since last update and the removal of redundant updates and synchronization with the physics engine and the Rasterizer.

Vizualizarea arborelui de selecţie

Arborele de Delimitare a Volumelor Dinamice, (DBVT) este folosit pentru a construi un arbore cu obiectele grafice din scenă. Elementele arborelui sunt cutii AABB (Aligned Axis Bounding Boxes) în care sunt incluse obiectele. Acest lucru oferă o bună precizie în scenele închise şi deschise. Acest nou sistem este activat în mod implicit, dar poate fi dezactivat cu un buton în setările World. Cu aceste îmbunătăţiri, selecţia şi o parte graficii Scenei devin de 5 ori mai rapide decât în versiunea ​​2.48. Cu toate acestea, viteza de lucru este vizibilă doar când ai mai multe obiecte (>100).

Selecţia ocluziilor

Selecţia ocluziilor se referă la abilitatea unor obiecte (occluders) de a ascunde alte obiecte (adică de a nu le trimite către GPU). Implementarea este realizată identic ca la arborele de selecţie.

Selecţia ocluziilor nu este activată implicit pentru că este o facilitate care cere mai întâi înţelegerea ei pentru a aduce mai multe beneficii. Dacă nu este folosită corect, ar putea încetini jocul. (Nu pre mult, totuşi, pentru că timpul de procesare se autoreglează.)

Cum funcţionează

Selecţia ocluziilor se activează atunci când defineşti cel puţin un "occluder" în scenă. Opţiunea pentru Occluder se află la butoanele pentru fizică (physics):

Dev-GameEngine-occlusion-button.png


Opţiunea "Occluder" trebuie folosită doar pe obiecte de tip reţea. ..........As far as Physics is concerned, it is equivalent to "No collision".  The reason why I chose to make the Occluder mode mutually exclusive with other physics mode is to emphasize on the fact that occluders should be specifically designed for that purpose and not every mesh should be an occluder. However, you can enable the Occlusion capability on physics objects using Python and Logic bricks. We'll come to that.

When an occluder object enters the view frustrum, the BGE builds a ZDepth buffer from the faces of that object. Whether the faces are one-side or two-side is important: only the front faces and two-side faces are used to build the ZDepth buffer. If multiple occluders are in the view frustrum, the BGE combines them and keeps the most foreground faces.

The resolution of the ZDepth buffer is controllable in the World settings with the "Occlu Res" button:

Dev-GameEngine-occlusion-resolution.png

By default the resolution is 128 pixels for the largest dimension of the viewport while the resolution of the other dimension is set proportionally. Although 128 is a very low resolution, it is sufficient for the purpose of culling. The resolution can be increased to maximum 1024 but at great CPU expense.

The BGE traverses the DBVT tree and for each node checks if it is entirely hidden by the occluders and if so, culls the node (and all the objects it contains).

To further optimize the feature, the BGE builds and uses the ZDepth buffer only when at least one occluder is in the view frustrum. Until then, there is no performance decrease compared to regular view frustrum culling.

How to use it

There are situations where occlusion culling will not bring any benefit:

  • If the occluders are small and don't hide many objects.
    In that case, occlusion culling is just dragging your CPU down.
  • If the occluders are large but hides simple objects.
    In that case you're better off sending the objects to the GPU.
  • If the occluders are large and hides many complex objects but in a very predictable way.
    Example: a house full of complex objects. Although occlusion culling will perform well in this case, you will get better performance by implementing a specific logic that hides/unhides the objects; for instance making the objects visible only when the camera enters the house.

Occlusion culling makes most sense when the occluders are large objects (buildings, mountains, ...) that hide many complex objects in an unpredictable way. However, don't be too concerned about performance: even if you use it inappropriately, the performance decrease will be limited due to the structure of the algorithm.

Occluders can be visible graphic objects but beware that too many faces will make the ZDepth buffer creation slow. For example, a terrain is not a good candidate for occlusion: too many faces and too many overlap. Occluder can be invisible objects placed inside more complex objects (ex: "in the walls" of a building with complex architecture). Occluders can have "holes" through which you will see objects.

Here is a possible workflow to create occluders from a complex terrain:

  • duplicate the terrain and make it low poly
  • remove all horizontal parts and keep only the high elevation parts
  • make all the face invisible and set the Occluder mode.

To optimize further, you may split the occluder into several objects (make an occluder from each mountain, each wall, etc.) and do the same for the terrain: this way, parts of the terrain that are behind occluders will not be rendered.

You can verify how the occlusion is working by running the game in wireframe mode.

In-game control

You can turn on/off the occlusion capability of an object with Python:

obj.occlusion = True
obj.setOcclusion(True, False)    #param1=occlusion, param2=recurse in children

The object doesn't need to be defined as an occluder in the GUI: you can enable occlusion capability on any mesh object, including static and dynamic objects during the game.

You can also use the Visibility Actuator:

Dev-GameEngine-occlusion-brick.png


Note that the layout of the actuator has changed: The Visible/Invisible mutually exclusive buttons have been replaced by two independent buttons: push the button to activate the feature (Visible/Occluding), unpush the button to activate the opposite feature (Invisible/Non-occluding).

Note that the actuator sets the Visibility and Occlusion mode at the same time. If you need to set them separately, use Python.

Known limitation

  • If you want to use occlusion culling, you must at least have one occluder at the start of the game. The occluder doesn't need to be in an active layer. After that, you can enable and disable occlusion capability on every mesh objects during the game using on the In-game control.