[Orxonox-commit 4792] r9461 - code/branches/shaders/src/orxonox/graphics

davidsa at orxonox.net davidsa at orxonox.net
Tue Nov 20 18:46:04 CET 2012


Author: davidsa
Date: 2012-11-20 18:46:03 +0100 (Tue, 20 Nov 2012)
New Revision: 9461

Modified:
   code/branches/shaders/src/orxonox/graphics/Billboard.cc
   code/branches/shaders/src/orxonox/graphics/Billboard.h
   code/branches/shaders/src/orxonox/graphics/LensFlare.cc
   code/branches/shaders/src/orxonox/graphics/LensFlare.h
Log:
Updated orxonox::Billboard so you can disable FrustumCulling. Also improved orxonox::LensFlare and added documentation.

Modified: code/branches/shaders/src/orxonox/graphics/Billboard.cc
===================================================================
--- code/branches/shaders/src/orxonox/graphics/Billboard.cc	2012-11-19 15:25:11 UTC (rev 9460)
+++ code/branches/shaders/src/orxonox/graphics/Billboard.cc	2012-11-20 17:46:03 UTC (rev 9461)
@@ -179,4 +179,13 @@
             bSet->setRenderQueueGroup(groupID);
         }
     }
+    
+    void Billboard::disableFrustumCulling()
+    {
+        Ogre::BillboardSet* bSet = this->billboard_.getBillboardSet();
+        if( bSet != NULL )
+        {
+            bSet->setBounds(Ogre::AxisAlignedBox(Ogre::AxisAlignedBox::EXTENT_INFINITE),0);
+        }
+    }
 }

Modified: code/branches/shaders/src/orxonox/graphics/Billboard.h
===================================================================
--- code/branches/shaders/src/orxonox/graphics/Billboard.h	2012-11-19 15:25:11 UTC (rev 9460)
+++ code/branches/shaders/src/orxonox/graphics/Billboard.h	2012-11-20 17:46:03 UTC (rev 9461)
@@ -82,6 +82,8 @@
             void setDefaultDimensions(float width, float height);
             
             void setRenderQueueGroup(unsigned char groupID);
+            
+            void disableFrustumCulling();
 
 
         protected:

Modified: code/branches/shaders/src/orxonox/graphics/LensFlare.cc
===================================================================
--- code/branches/shaders/src/orxonox/graphics/LensFlare.cc	2012-11-19 15:25:11 UTC (rev 9460)
+++ code/branches/shaders/src/orxonox/graphics/LensFlare.cc	2012-11-20 17:46:03 UTC (rev 9461)
@@ -46,7 +46,7 @@
 {
     CreateFactory(LensFlare);
     
-    LensFlare::LensFlare(BaseObject* creator) : StaticEntity(creator), scale_(1.0f)
+    LensFlare::LensFlare(BaseObject* creator) : StaticEntity(creator), scale_(1.0f), fadeOnViewBorder_(true), fadeResolution_(7), fadeExponent_(2.0f)
     {
         RegisterObject(LensFlare);
         
@@ -63,55 +63,122 @@
     {
         SUPER(LensFlare, XMLPort, xmlelement, mode);
         XMLPortParam(LensFlare, "scale", setScale, getScale, xmlelement, mode).defaultValues(1.0f);
+        XMLPortParam(LensFlare, "fadeOnViewBorder", setFadeOnViewBorder, isFadeOnViewBorder, xmlelement, mode).defaultValues(true);
+        XMLPortParam(LensFlare, "fadeResolution", setFadeResolution, getFadeResolution, xmlelement, mode).defaultValues(7);
+        XMLPortParam(LensFlare, "fadeExponent", setFadeExponent, getFadeExponent, xmlelement, mode).defaultValues(2.0f);
     }
     
     void LensFlare::registerVariables()
     {
-        registerVariable(this->scale_, VariableDirection::ToClient, new NetworkCallback<LensFlare>(this, &LensFlare::updateBillboardPositions));
+        registerVariable(this->scale_, VariableDirection::ToClient);
+        registerVariable(this->fadeOnViewBorder_, VariableDirection::ToClient);
+        registerVariable(this->fadeResolution_, VariableDirection::ToClient);
     }
-    
+
+    /**
+    @brief
+        This function creates all the billboards needed for the flare effect
+    */
     void LensFlare::createBillboards()
     {
+        //TODO: add more billboards, possibly do some cleaning up, by using a loop
         this->occlusionBillboard_ = new Billboard(this);
         this->occlusionBillboard_->setMaterial("lensflare/hoq");
         this->occlusionBillboard_->setPosition(this->getPosition());
         this->occlusionBillboard_->setVisible(false);
+        this->occlusionBillboard_->disableFrustumCulling();
         this->occlusionBillboard_->setRenderQueueGroup(RENDER_QUEUE_HOQ);
         this->attach(this->occlusionBillboard_);
         
         Billboard* burst = new Billboard(this);
         burst->setMaterial("lensflare/burst");
         burst->setPosition(this->getPosition());
-        burst->setVisible(false);
+        burst->disableFrustumCulling();
+        burst->setVisible(true);
         this->attach(burst);
     }
+
+    /**
+    @brief
+        This function updates the states of all the billboards, i.e. their positions, visibilty and dimensions
+    @param dimension
+        the current dimension of the main billboard, we're always using square billboards
+    */
+    void LensFlare::updateBillboardStates(unsigned int dimension, bool lightIsVisible)
+    { 
+        //TODO: position and dimensions need to be calculated for everything but the main burst of the flare
+        for(std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++) {
+            Billboard* billboard=static_cast<Billboard*>(*it);
+            billboard->setPosition(this->getPosition());
+            billboard->setVisible(lightIsVisible);
+            billboard->setDefaultDimensions(dimension,dimension);
+        }
+    }
+
+    /**
+    @brief
+        This function updates the alpha values for all billboards except for the one used for Hardware Occlusion Querying
+    @param alpha
+        the new alpha value all visible billboards should use
+    */
+    void LensFlare::updateBillboardAlphas(float alpha)
+    {
+        ColourValue* colour = new ColourValue(1.0f,1.0f,1.0f,alpha);
+        std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin();
+        it++;
+        for(;it!=this->getAttachedObjects().end(); it++) {
+            Billboard* billboard=static_cast<Billboard*>(*it);
+            billboard->setColour(*colour);
+        }
+        delete colour;
+    }
     
-    void LensFlare::updateBillboardPositions()
+    /**
+    @brief
+        This function generates point samples of the main burst billboard according to the fadeResolution and returns how many of them are in the view port
+    @param dimension
+        the current dimension of the main billboard, we're always using square billboards
+    @return
+        the absolute amount of point samples that are currently captured by the camera of the view port
+    */
+    unsigned int LensFlare::getPointCount(unsigned int dimension) const
     {
-        Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera(); //get active Ogre Camera Instance, so we can check whether the light source is visible
-        bool lightIsVisible=camera->isVisible(this->getPosition()); //is the light source visible from our point of view?
-        this->cameraDistance_=camera->getPosition().distance(this->getPosition());
-        unsigned int dimension=this->cameraDistance_*this->scale_;
-        
-        this->occlusionBillboard_->setPosition(this->getPosition());
-        this->occlusionBillboard_->setVisible(lightIsVisible);
-        this->occlusionBillboard_->setDefaultDimensions(dimension,dimension);
-        
-        Billboard* burst=static_cast<Billboard*>(getAttachedObject(1));
-        burst->setPosition(this->getPosition());
-        burst->setVisible(lightIsVisible);
-        burst->setDefaultDimensions(dimension,dimension);
+        Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera();
+        Vector3 position = this->getPosition();
+        Vector3 nX = camera->getOrientation().xAxis().normalisedCopy();
+        Vector3 nY = camera->getOrientation().yAxis().normalisedCopy();
+        int halfRes=fadeResolution_/2;
+        int resDim=dimension/fadeResolution_;
+        unsigned int count=0;
+        for(int i=-halfRes;i<=halfRes;i++)
+        {
+            for(int j=-halfRes;j<=halfRes;j++)
+            {
+                Vector3 point=position+(i*resDim)*nX+(j*resDim)*nY;//generate point samples
+                if(camera->isVisible(point))
+                {
+                    count++;
+                }
+            }
+        }
+        return count;
     }
 
     void LensFlare::tick(float dt)
     {
         if(this->isVisible())
         {
-            updateBillboardPositions();
-            if(this->occlusionBillboard_->isVisible()) {
-                unsigned int dimension=this->cameraDistance_*this->scale_;
+            Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera(); //get active Ogre Camera Instance, so we can check whether the light source is visible
+            this->cameraDistance_=camera->getPosition().distance(this->getPosition());
+            unsigned int dimension=this->cameraDistance_*this->scale_;
+            if(!this->fadeOnViewBorder_)
+            {
+                this->fadeResolution_=3;//this is so we can still determine when the billboard has left the screen
+            }
+            unsigned int pointCount=this->getPointCount(dimension);
+            updateBillboardStates(dimension,pointCount>0);
+            if(pointCount>0) {
                 Ogre::Sphere* sphere=new Ogre::Sphere(this->getPosition(),dimension*0.25);
-                Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera();
                 float left, right, top, bottom;
                 camera->projectSphere(*sphere,&left,&top,&right,&bottom);//approximate maximum pixel count of billboard with a sphere
                 delete sphere;
@@ -119,18 +186,21 @@
                 Ogre::RenderWindow* window = GraphicsManager::getInstance().getRenderWindow();
                 float maxCount=(right-left)*(top-bottom)*window->getWidth()*window->getHeight()*0.25;
                 float pixelCount=this->getScene()->getRenderQueueListener()->getPixelCount();//get pixel count
-                float ratio=pixelCount/maxCount;
-                //orxout() << "maxCount: " << maxCount << " HOQ: " << pixelCount << " ratio: " << ratio << std::endl;
-                ColourValue* colour = new ColourValue(1.0f,1.0f,1.0f,ratio); //adjust alpha of billboard
+                float ratio=(maxCount==0)?0:(pixelCount/maxCount);//prevent division by zero
+                float borderRatio=1.0f;
+                if(this->fadeOnViewBorder_)
+                {
+                    borderRatio=((float) pointCount)/(((float) fadeResolution_)*((float) fadeResolution_));//ratio for the border fade
+                }
                 
-                Billboard* burst=static_cast<Billboard*>(getAttachedObject(1));
-                burst->setColour(*colour);
-                delete colour;
+                //update alpha values of all billboards except the HOQ billboard
+                this->updateBillboardAlphas(std::min(1.0f,std::pow(std::min(ratio,borderRatio),2.0f)));
             }
         }
     }
 
     void LensFlare::changedVisibility()
     {
+      
     }
 }
\ No newline at end of file

Modified: code/branches/shaders/src/orxonox/graphics/LensFlare.h
===================================================================
--- code/branches/shaders/src/orxonox/graphics/LensFlare.h	2012-11-19 15:25:11 UTC (rev 9460)
+++ code/branches/shaders/src/orxonox/graphics/LensFlare.h	2012-11-20 17:46:03 UTC (rev 9461)
@@ -57,7 +57,7 @@
     //TODO: The Hardware Occlusion only works properly for a single Flare on the screen,
     // if we have multiple strong lights it'll become way more complicated to determine how much of every object is occluded individually
     // there's below a 100 render queue groups, so maybe we should take turns for each object to be tested, so we only have one of the objects rendered at a time
-    // obviously we shouldn't use too much of these effects anyways, since they use a lot of performance, so not sure whether it's worth implementing a solution that works for multiple lens flares on screen 
+    // obviously we shouldn't use too many of these effects anyways, since they use a lot of processing power, so not sure whether it's worth implementing a solution that works for multiple lens flares on screen 
     class _OrxonoxExport LensFlare : public StaticEntity, public Tickable
     {
         public:
@@ -66,8 +66,62 @@
             
             inline void setScale(float scale)
                 { this->scale_=scale; }
-            inline float getScale()
+            inline float getScale() const
                 { return this->scale_; }
+                
+            /**
+            @brief
+                This sets the resolution of the out-of-screen-fade-effect
+                
+                the higher the resolution, the smoother the transition, but it will also have a greater impact on the performance
+                this happens with O(n^2) since it's a two dimensional operation.
+            @param fadeResolution
+                how many point samples should be used per axis
+                
+                note: this will always be an odd number, so the center point is included in the samples
+            */
+            inline void setFadeResolution(unsigned int fadeResolution)
+                { this->fadeResolution_=fadeResolution>0?fadeResolution:1; }
+            /**
+            @brief
+                This returns the resolution of the out-of-screen-fade-effect
+            @return how many point samples are being used per axis
+            */
+            inline unsigned int getFadeResolution() const
+                { return this->fadeResolution_; }
+                
+            /**
+            @brief
+                This sets the exponent of the fade-out function
+            @param exponent
+                how strong should the fade-out effect be
+            */
+            inline void setFadeExponent(float exponent)
+                { this->fadeExponent_=exponent; }
+            /**
+            @brief
+                This returns the exponent of the fade-out function
+            @return the exponent of the fade-out function
+            */
+            inline float getFadeExponent() const
+                { return this->fadeExponent_; }
+                
+            /**
+            @brief
+               Turn the out-of-screen-fade-effect on or off
+            @param fadeOnViewBorder
+                true to turn the effect on, false to turn it off
+            */
+            inline void setFadeOnViewBorder(bool fadeOnViewBorder)
+                { this->fadeOnViewBorder_=fadeOnViewBorder; }
+            /**
+            @brief
+               Determine whether the out-of-screen-fade-effect is on or off
+            @return
+                true if the effect is on, false if it is off
+            */
+            inline bool isFadeOnViewBorder() const
+                { return this->fadeOnViewBorder_; }
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
 
@@ -80,11 +134,18 @@
             
             void createBillboards();
             
-            void updateBillboardPositions();
+            void updateBillboardStates(unsigned int dimension, bool isLightVisible);
             
-            Billboard* occlusionBillboard_;
-            unsigned int cameraDistance_;
-            float scale_;
+            void updateBillboardAlphas(float alpha);
+            
+            unsigned int getPointCount(unsigned int dimension) const;
+            
+            Billboard* occlusionBillboard_;//!< this is a transparent billboard used solely for the Hardware Occlusion Query
+            unsigned int cameraDistance_;//!< current distance of the lensflare center from the camera
+            float scale_;//!< this factor is used to scale the billboard to the desired size
+            bool fadeOnViewBorder_;//!< should the effect fade out on the border of the view?
+            unsigned int fadeResolution_;//!< how many points should be sampled per axis for the screen border fade. High number => smooth fade, but uses more processing power
+            float fadeExponent_;//!< this determines how fast the flare fades away as it gets obstructed
     };
 }
 




More information about the Orxonox-commit mailing list