テンプレート:Release Notes/2.49/Game Engine/Optimization/Culling
目次
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):
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:
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:
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.