Skip to main content
History: ScreenRatioLodStrategy
View published page
Source of version: 1
(current)
!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 {CODE(wrap="1", colors="c++")} // 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"); {CODE} !!How to use LODed mesh ''NOTE: code needs testing'' {CODE(wrap="1", colors="c++")} Entity* enty = sceneManager->createEntity("MyLodMesh", "something-with-lod.mesh"); enty->setLodStrategy(new Ogre::ScreenRatioLodStrategy()); // optional {CODE} !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 {CODE(wrap="0", colors="c++")} #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 {CODE} !!.CPP {CODE(wrap="0", colors="c++")} #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); } {CODE} !References http://www.ogre3d.org/tikiwiki/PixelCountLodStrategy
Search by Tags
Search Wiki by Freetags
Latest Changes
Compiled API Reference
Overlay Editor
Introduction - JaJDoo Shader Guide - Basics
RT Shader System
RapidXML Dotscene Loader
One Function Ogre
One Function Ogre
...more
Search
Find
Online Users
141 online users
OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username
Password
CapsLock is on.
Remember me (for 1 year)
Log in