If you haven't done so already, be sure to visit the Wiki Portal to read about how the wiki works. Especially the Ogre Wiki Overview page.
Screen Ratio LOD Strategy
ScreenRatioLodStrategy works by analyzing how much portion of screen a model occupies on screen on any given instance of time, and selects a LOD mesh/material accordingly. ScreenRatioLodStrategy is inspired by PixelCountLodStrategy.
Status
- ScreenRatioLodStrategy is slight modification of PixelCountLodStrategy.
- Currently it is not included in Ogre SDK
Inspiration
I feel ScreenRatioLodStrategy does a little more justice to varying screen resolutions these days.
Say, I specify a PixelCountLodStrategy mesh with 50% complexity reduction below 500*500 pixel area. Now this might work very well on my 1080p monitor, but when I view the same model on a 1024*800 netbook screen or projector, model will switch to level 1 a little too soon.
ScreenRatioLodStrategy on the other hand specifies the Ratio below which lod will be reduced. We spacify lod values as 0.2(=20%), 0.1(=10%) and so on. So when a model takes below 20% of total screen area, it will switch to level 1. This is total independent of whether I am running a 800*600 projector or a 1080p monitor.
ScreenRatioLodStrategy VS PixelCountLodStrategy
- ScreenRatioLodStrategy is inspired by PixelCountLodStrategy, but provide simpler and better control over LOD meshes.
- Where PixelCountLodStrategy specifies LOD meshes when they occupy certain number pixels on screen (eg 500*500pixels, 200*200), ScreenRatioLodStrategy specifies LOD meshes when they occupy certain percent of total screen area (50% of screen, 20% of screen)
- Easier to specify lod values while defining LOD meshes
ScreenRatioLodStrategy Values
NOTE: values need testing
LOD values are specified as ratio, that is, area occupied by a model of total screen area. However please note that the values are approximations and generally higher than actual area. For example
- LOD Value > 1.0 = majority of screen space (~50%)
- LOD Value > 0.5 = significant amount of screen space (~25%)
- LOD Value > 0.2 = small amount of screen space (~5%)
- and so on
How To Programatically Prepare A Mesh For ScreenRatioLodStrategy ?
NOTE: code needs testing
For ScreenRatioLodStrategy , mesh lod values are stored in decreasing orger, starting with MAX_FLOAT value. Here is what you have to do
// define base mesh MeshPtr mesh = MeshManager::getSingleton().load("something-100p.mesh"); // level 0, 100 percent // add LOD strategy mesh->setLodStrategy(new Ogre::ScreenRatioLodStrategy()); // might need to reapply after load // add level 1 mesh mesh->createManualLodLevel(0.5, "something-50p.mesh"); // level 1, 50 percent // add level 2 mesh, for pixel area below 200*200 mesh->createManualLodLevel(0.2, "something-25p.mesh"); // level 2, 25 percent // export LODed mesh MeshSerializer ser; ser.exportMesh(mesh1.get(), "something-with-lod.mesh");
How to use LODed mesh
NOTE: code needs testing
Entity* enty = sceneManager->createEntity("MyLodMesh", "something-with-lod.mesh"); enty->setLodStrategy(new Ogre::ScreenRatioLodStrategy()); // optional
Help Needed
- Currently it does not implement Singleton interface, if someone can do it
- I could not decide if I need to do something in transformBias function
CODE
.H
#ifndef __Screen_Ratio_Lod_Strategy_H__ #define __Screen_Ratio_Lod_Strategy_H__ #include "Ogre.h" #include "OgreLodStrategy.h" using namespace Ogre; // TODO add singleton interface class SUBMERGE_API ScreenRatioLodStrategy : public LodStrategy { protected: virtual Real getValueImpl(const MovableObject *movableObject, const Camera *camera) const; public: ScreenRatioLodStrategy(); virtual Real getBaseValue() const; virtual Real transformBias(Real factor) const; virtual ushort getIndex(Real value, const Mesh::MeshLodUsageList& meshLodUsageList) const; virtual ushort getIndex(Real value, const Material::LodValueList& materialLodValueList) const; virtual void sort(Mesh::MeshLodUsageList& meshLodUsageList) const; virtual bool isSorted(const Mesh::LodValueList& values) const; }; #endif
.CPP
#include "ScreenRatioLodStrategy.h" ScreenRatioLodStrategy::ScreenRatioLodStrategy() : LodStrategy("ScreenRatio") { } Real ScreenRatioLodStrategy::getValueImpl(const MovableObject *movableObject, const Ogre::Camera *camera) const { // Get area of unprojected circle with object bounding radius Real boundingArea = Math::PI * Math::Sqr(movableObject->getBoundingRadius()); // Base computation on projection type switch (camera->getProjectionType()) { case PT_PERSPECTIVE: { // Get camera distance Real distanceSquared = movableObject->getParentNode()->getSquaredViewDepth(camera); // Check for 0 distance if (distanceSquared <= std::numeric_limits<Real>::epsilon()) return getBaseValue(); // Get projection matrix (this is done to avoid computation of tan(fov / 2)) const Matrix4& projectionMatrix = camera->getProjectionMatrix(); // Estimate pixel ratio return (boundingArea * projectionMatrix[0][0] * projectionMatrix[1][1]) / distanceSquared; } case PT_ORTHOGRAPHIC: { // Compute orthographic area Real orthoArea = camera->getOrthoWindowHeight() * camera->getOrthoWindowWidth(); // Check for 0 orthographic area if (orthoArea <= std::numeric_limits<Real>::epsilon()) return getBaseValue(); // Estimate pixel ratio return boundingArea / orthoArea; } default: { // This case is not covered for obvious reasons throw; } } } //--------------------------------------------------------------------- Real ScreenRatioLodStrategy::getBaseValue() const { // Use the maximum possible value as base return std::numeric_limits<Real>::max(); } //--------------------------------------------------------------------- Real ScreenRatioLodStrategy::transformBias(Real factor) const { // No transformation required for pixel ratio strategy return factor; } //--------------------------------------------------------------------- ushort ScreenRatioLodStrategy::getIndex(Real value, const Mesh::MeshLodUsageList& meshLodUsageList) const { // Values are descending return getIndexDescending(value, meshLodUsageList); } //--------------------------------------------------------------------- ushort ScreenRatioLodStrategy::getIndex(Real value, const Material::LodValueList& materialLodValueList) const { // Values are descending return getIndexDescending(value, materialLodValueList); } //--------------------------------------------------------------------- void ScreenRatioLodStrategy::sort(Mesh::MeshLodUsageList& meshLodUsageList) const { // Sort descending sortDescending(meshLodUsageList); } //--------------------------------------------------------------------- bool ScreenRatioLodStrategy::isSorted(const Mesh::LodValueList& values) const { // Check if values are sorted descending return isSortedDescending(values); }
References
http://www.ogre3d.org/tikiwiki/PixelCountLodStrategy
Contributors to this page: coreSOLO
.
Page last modified on Tuesday 20 of July, 2010 06:55:50 UTC by coreSOLO
.
The content on this page is licensed under the terms of the Creative Commons Attribution-ShareAlike License.
As an exception, any source code contributed within the content is released into the Public Domain.

