- About Level of Detail (LOD)
- Creating Detail Levels
- LOD Selection
- LOD System Blacklisting
- Dynamic LOD Budget Adjustment (CET 9.0 and above)
- Insert Animation and LOD
- Blocks and LOD
About Level of Detail (LOD)
This works based on the principle that, if a model is located far away from the camera (user point of view), it covers fewer pixels on a screen, compared to when it is close. In other words, if a model is far away, it is much harder to perceive fine details compared to when it is close to the viewpoint.
For example, given a chair model, when observed from 1m away, you may need to generate close up details such as the wheels, the armrest, and the ridges at the back to ensure graphical fidelity; but when observed from 100m away, perhaps only things like the back of the chair and the seat need to be created, and they can be created in a much simpler form (say, a box), since the users won't be able to perceive very fine details when the chair is so far away.
In CET, four different LODs are used to represent a model, ranging from Low, Medium, High, Super; with Super being the most detailed LOD, and Low, the least detailed. The teapot snapper (located at Wall Drawings tab in Dev mode) can be used to test the behavior of the LOD system.
Creating Detail Levels
Usually, the detail of a model is controlled by manipulating the number of polygons in the model, but different materials can also be used to increase performance. There exists a system recommendation (budget) of polygon count, please ensure that your snappers adhere to the budget for each detail level, by using the Model Performance dialog to check your snappers or models!
For PGC Snappers
- Detail levels can be created in get3D/build3D by checking the current FetchEnv3D's detail, and then adjusting the fidelity of your graphics manually. For example, a cylinder at High detail may have had a higher refinement level in comparison to a cylinder at Low detail.
- Ensure that an appropriate detail mask is set (by overriding
Snapper.detailMask
).- Detail Masks are used to declare to the system what LODs your snapper is able to support.
- If your snapper only supports Medium detail for example, but your detail mask declares that it supports High, Medium, and Low, this will result in the system unnecessarily switch between detail levels, causing a performance hit.
- If your snapper supports High, Medium, and Low, but your detail mask only declares Medium (which happens when you use
defaultDetailMask
), your High and Low LODs will not be switched to.
- If cmsym is used, check the article on cmsym on how to add LOD.
For Data Models
- Detail levels can be created using Model Lab or Batch Converter reducers.
LOD Selection
CET automatically chooses which detail level to switch to represent the model on-screen, based on the following criteria:
- The context of the render (Realtime rendering, or Photographic Rendering)
- The frame rate of the application determining the system budget, prioritized by the number of pixels (CET 9.0 and above)
- The number of pixels that the model currently covers on screen (CET 8.5 and below)
During Realtime Rendering (i.e. in 3D view)
- We will only use High, Medium, and Low.
- (CET 8.5 and below) The more close-up an object is, the higher the detail level displayed.
- (CET 9.0 and above) The faster the framerate of the application, the more budget we allocate to higher detail levels, and CET will attempt to display higher or lower detail to maximize performance. The priority of allocating the budget, given a tie, is decided based on object distance and user selection. See the section below, Dynamic LOD Budget adjustment for more details.
During Photo Rendering
- We will use Super, in addition to High, Medium, and Low.
- The more close-up an object is, the higher the detail level displayed.
LOD System Blacklisting
The LOD system has a blacklist feature to prevent certain badly made huge models from slowing overall 3D performance, by prohibiting them from swapping LODs ("banned") if they have exceeded the allocated time limit to switch LODs.
- The blacklist identifies snappers using the snapper's
meshKey3D
, or the sym'sstructuralKey
. - Users are now able to press Shift+F5 to clear the blacklist.
- Press 0 key in develop mode to dump models that are currently being blacklisted.
- After being banned, we will now attempt to swap the model to a lower level of detail.
- New traces and warning messages have been added in develop mode, displaying what snappers are being blacklisted and going to be permanently banned.
RED realtime LOD: blacklisted z=CatKitchenAcc((id=6, orig)), failCount=1 > Blacklisted means that the snapper is taking too long to swap between LODs, and being blacklisted for more than 4 times will result in the snapper being banned from switching LODs for the current session. RED realtime LOD: blacklisted z=CatKitchenAcc((id=6, orig)), failCount=2 RED realtime LOD: blacklisted z=CatKitchenAcc((id=6, orig)), failCount=3 RED realtime LOD: blacklisted z=CatKitchenAcc((id=6, orig)), failCount=4 CatKitchenAcc((id=6, orig)) is blacklisted for >4 times, hence it will be swapped to lower LOD and banned from switching LODs for the rest of the session.
Recap: Recall that you can override meshKey3D() method in snapper.cm to control the mesh key used for blacklisting. This is of particular importance for snappers that dynamically generate 3D using data-driven approaches or proxies, as the default meshKey3D
returns the snapper's class name. As a result, it is possible for all your snappers that share the same class but have different 3D data, to be blacklisted even if only one of the data has slow 3D. To resolve this, override the following method in your snapper to include a unique key for the mesh data.
/** * Return a key grouping all objects with similar 3D visuals. */ extend public str meshKey3D() { Class c = class; return concat(c.name, ';', c.pkgKey) ; }
Dynamic LOD Budget Adjustment (CET 9.0 and above)
Starting CET 9.0, we have implemented a basic version of a dynamic LOD updator. CET will attempt to dynamically adjust the LOD budget to increase or decrease the amount of high LODs used in the 3D view, based on current system performance (which includes metrics like frame rate).
Basically, the idea is that if the drawing is fast enough in real-time 3D and your computer has more than enough power, we should be able to use High LODs for more objects. This helps to avoid switching around different LOD models all the time.
The normal behavior is that if you have a fast enough computer, you may have noticed that some of your drawings have all objects "stuck" at high LOD after a while, instead of switching between High and Medium for instance when you pan or zoom around.
The frame rate determines the budget of the system (i.e. how much High/Medium/Low LOD objects can be in the drawing at any given time), and then CET tries to show as much higher detail objects as the system allows. An example would be, the system allocates a budget of 50 High snappers, and your drawing has 200 snappers, up to 50 objects will be allowed to show High details (regardless of their pixel size), however, the priority in which the snappers are selected is based on pixel size. This means an object currently at a distance that would show Medium size in 8.5, may display High if the system budget allows.
Developer's Note
- You can press Shift+F+P+S to open a dialog to help monitor the current system LOD budget and graphics draw time performance.
- If you wish to turn this off for now for development purposes, you can revert to the pre-9.0 behavior which is based on pixel size, through Developer Tools > Monitor > Uncheck Enable LOD Budget Update.
Insert Animation and LOD
In 9.0, we have also added the ability for snapper insert animation to use high LODs whenever possible.
As a start, the working conditions are:
- It will only work with objects using the new
InsertAnimationG2
. - It won't work if the selection has too many objects (the current limit is 5).
- It won't work with inserting favorites, or blocks.
- It is also subject to blacklisting above, so it also doesn’t work if it takes too long.
Blocks and LOD
Starting CET 9.0, we have added backend support for snappers contained in a block to display LODs. Please refer to the migration guide for details: https://www.configura.com/wiki/index.php/Migration_from_8.5_to_9.0#Blocks_and_LOD_System_Enhancements
- Rendering also uses the same solution and hence will be able to show correct LODs as well.
- Individual snappers in a block are also subjected to the blacklisting system above.
Developer's Note
A block is defined as the core BlockSnapper
(cm.core.block), which has a reference to Block
and generates graphics from BlockSpace
, which contains the subsnappers contained in a block. A block can also refer to other normal Snappers that have overridden this method, Snapper::isBlock()
, to make themselves a block. They may or may not have reference to a Block
or BlockSpace
, and also may or may not actually contain subsnappers.
We have also added some new interfaces to BlockSpace
to control 3D graphics generation in a block, so you don't have to copy the whole build3D(..)
code just to add a line or two to exclude certain snappers. You should now instead override one of the following methods to control subsnapper visibility:
/** * Override this to control whether we allow early exit. */ extend public bool timeLimitExceeded(FetchEnv3D env) { return !env.withinAllowedTimeFrame(); } /** * Include 3D In Block - controls whether a snapper is shown when in a block. */ extend public bool include3DInBlock(Snapper s, Snapper blockSnapper, FetchEnv3D env) { return s.visibleOutsideBlock() and !s.deny3D(); } /** * Include 3D in frozen - controls whether a snapper is shown when in a freezer. */ extend public bool include3DInFrozen(Snapper s, Snapper blockSnapper, FetchEnv3D env) { return s.visibleOutsideBlock() and !s.deny3D(); }
For custom block snappers, if the snapper utilizes graphics from BlockSpace
, in most cases, they will get the new behaviors for free. However, if the block snapper does not utilize graphics from BlockSpace
or has add-on additional graphics, then you would have to use FetchEnv3D::putCurrentEntry(owner, prim)
to add on additional graphics.
Comments
0 comments
Please sign in to leave a comment.