英文原文:http://www.ogre3d.org/wiki/index.php/Displaying_LensFlare
本教程和代码作者User:Sphinkie
翻译:痞子龙 http://blog.youkuaiyun.com/pizi0475
镜头光晕效应是在强光的视野内一个镜头出现时产生的光学效应。

效果是由如下合成的:光环(如一个光辉的圆圈)或“放射”(如一颗璀璨明星)。通常情况下 需要背景透明的TGA或PNG图像文件。


在计算机上,这种效应可以在二维或三维渲染。
二维方法
在镜头前创建一架飞机。 光晕将会在这架飞机上画出。
C:在屏幕的中心。
L:光源投射到屏幕后的中心。
现在,通过C和L绘制一条线D ,光晕就在线段的中心
原理可以在gamedev.net(奥斯汀游戏大会)找到。
三维方式
在镜头前和光源之间创建一条三维线段。沿着这条线绘制发散的光晕。
L:该光源位置
C:照相机的位置
R:C和L之间的距离
F:这一点在镜头前,它与光相同的距离和摄像机相同。 (沿着摄像机的方向画一条长度为R的线)。
利用L和F画一条线,光晕的位置就在线的中央或者1/3处
添加下面的代码会有更好的效果代码
Type Position Scale
Main d 1
halo d/2 1/2
burst d/3 1/4
halo d/5 1
burst -d/2 1/2
halo -d/4 1/4
burst -d/5 1/4
下面的代码将使用三维方法。
代码并不完美,因为效果是有点远离相机,一些3D物体之间可以通过摄像机和效果。
代码不是很难,需要大量的尝试,调整一些参数效果会更好。
用法
这是LensFlare类。
通过createLensFlare函数创建 lensflare,根据摄像机的位置和方向,然后调用update 更新frameListener,。
LensFlare.h
From Ogre Wiki
/* ------------------------------------------------------------------------- */ // File : LensFlare.h // Project : Long Forgotten Earth // Author : David de Lorenzo /* ------------------------------------------------------------------------- */ #ifndef _LENSFLARE_H_ #define _LENSFLARE_H_ #if _MSC_VER > 1000 #pragma once #endif #include "ogre.h" using namespace Ogre; /* ------------------------------------------------------------------------- */ /// A lens Flare effect. /** This class will create a lensflare effect, between The light position and the camera position. Some functions will allow to change the lensflare color effect, in case of coloured light, for instance. */ /* ------------------------------------------------------------------------- */ class LensFlare { public: LensFlare(Vector3 LightPosition, Camera* camera, SceneManager* SceneMgr); virtual ~LensFlare(); void createLensFlare(); void update(); void setVisible(bool visible); void setLightPosition(Vector3 pos); void setHaloColour(ColourValue color); void setBurstColour(ColourValue color); protected: SceneManager* mSceneMgr; Camera* mCamera; ColourValue mColour; SceneNode* mNode; BillboardSet* mHaloSet; BillboardSet* mBurstSet; Vector3 mLightPosition; bool mHidden; }; #endif
LensFlare.cpp
From Ogre Wiki
/* ------------------------------------------------------------------------- */ // File : LensFlare.cpp // Project : Long Forgotten Earth // Author : David de Lorenzo /* ------------------------------------------------------------------------- */ #include "LensFlare.h" /* ------------------------------------------------------------------------- */ /// Constructor /// @param LightPosition The 3D position of the Light, relative to the camera. /// @param camera The camera on which the lensflare effect will appear. /// @param SceneMgr Pointer on the SceneManager. /* ------------------------------------------------------------------------- */ LensFlare::LensFlare(Vector3 LightPosition, Camera* camera, SceneManager* SceneMgr) { mSceneMgr = SceneMgr; mCamera = camera; mHidden = true; this->createLensFlare(); this->setLightPosition(LightPosition); } /* ------------------------------------------------------------------------- */ /// Destructor /* ------------------------------------------------------------------------- */ LensFlare::~LensFlare() { mNode->detachObject(mHaloSet); mNode->detachObject(mBurstSet); mSceneMgr->removeBillboardSet(mHaloSet); mSceneMgr->removeBillboardSet(mBurstSet); /// TODO destroy mNode } /* ------------------------------------------------------------------------- */ /// this function creates and shows all the LensFlare graphical elements. /* ------------------------------------------------------------------------- */ void LensFlare::createLensFlare() { Real LF_scale = 2000; // ----------------------------------------------------- // We create 2 sets of billboards for the lensflare // ----------------------------------------------------- mHaloSet = mSceneMgr->createBillboardSet("halo"); mHaloSet->setMaterialName("lensflare/halo"); mHaloSet->setCullIndividually(true); mHaloSet->setQueryFlags(VOIDOBJECT); // They should not be detected by rays. mBurstSet= mSceneMgr->createBillboardSet("burst"); mBurstSet->setMaterialName("lensflare/burst"); mBurstSet->setCullIndividually(true); mBurstSet->setQueryFlags(VOIDOBJECT); // The node is located at the light source. mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); mNode->attachObject(mBurstSet); mNode->attachObject(mHaloSet); // ------------------------------- // Creation of the Halo billboards // ------------------------------- Billboard* LF_Halo1 = mHaloSet->createBillboard(0,0,0); LF_Halo1->setDimensions(LF_scale*0.5,LF_scale*0.5); Billboard* LF_Halo2 = mHaloSet->createBillboard(0,0,0); LF_Halo2->setDimensions(LF_scale,LF_scale); Billboard* LF_Halo3 = mHaloSet->createBillboard(0,0,0); LF_Halo3->setDimensions(LF_scale*0.25,LF_scale*0.25); // ------------------------------- // Creation of the "Burst" billboards // ------------------------------- Billboard* LF_Burst1 = mBurstSet->createBillboard(0,0,0); LF_Burst1->setDimensions(LF_scale*0.25,LF_scale*0.25); Billboard* LF_Burst2 = mBurstSet->createBillboard(0,0,0); LF_Burst2->setDimensions(LF_scale*0.5,LF_scale*0.5); Billboard* LF_Burst3 = mBurstSet->createBillboard(0,0,0); LF_Burst3->setDimensions(LF_scale*0.25,LF_scale*0.25); } /* -------------------------------------------------------------------------- */ /// This function updates the lensflare effect. /** This function should be called by your frameListener. */ /* -------------------------------------------------------------------------- */ void LensFlare::update() { // If the Light is out of the Camera field Of View, the lensflare is hidden. if (!mCamera->isVisible(mLightPosition)) { mHaloSet->setVisible(false); mBurstSet->setVisible(false); return; } else { mHaloSet->setVisible(true); mBurstSet->setVisible(true); } Real LightDistance = mLightPosition.distance(mCamera->getPosition()); Vector3 CameraVect = mCamera->getDirection(); // normalized vector (length 1) CameraVect = LightDistance * CameraVect; // The LensFlare effect takes place along this vector. Vector3 LFvect = (CameraVect - mLightPosition); //LFvect += Vector3(-64,-64,0); // sprite dimension (to be adjusted, but not necessary) // The different sprites are placed along this line. mHaloSet->getBillboard(0)->setPosition( LFvect*0.500); mHaloSet->getBillboard(1)->setPosition( LFvect*0.125); mHaloSet->getBillboard(2)->setPosition(-LFvect*0.250); mBurstSet->getBillboard(0)->setPosition( LFvect*0.333); mBurstSet->getBillboard(1)->setPosition(-LFvect*0.500); mBurstSet->getBillboard(2)->setPosition(-LFvect*0.180); // We redraw the lensflare (in case it was previouly out of the camera field, and hidden) this->setVisible(true); } /* ------------------------------------------------------------------------- */ /// This function shows (or hide) the lensflare effect. /* ------------------------------------------------------------------------- */ void LensFlare::setVisible(bool visible) { mHaloSet->setVisible(visible); mBurstSet->setVisible(visible); mHidden = !visible; } /* ------------------------------------------------------------------------- */ /// This function updates the light source position. /** This function can be used if the light source is moving.*/ /* ------------------------------------------------------------------------- */ void LensFlare::setLightPosition(Vector3 pos) { mLightPosition = pos; mNode->setPosition(mLightPosition); } /* ------------------------------------------------------------------------- */ /// This function changes the colour of the burst. /* ------------------------------------------------------------------------- */ void LensFlare::setBurstColour(ColourValue color) { mBurstSet->getBillboard(0)->setColour(color); mBurstSet->getBillboard(1)->setColour(color*0.8); mBurstSet->getBillboard(2)->setColour(color*0.6); } /* ------------------------------------------------------------------------- */ /// This function changes the colour of the halos. /* ------------------------------------------------------------------------- */ void LensFlare::setHaloColour(ColourValue color) { mHaloSet->getBillboard(0)->setColour(color*0.8); mHaloSet->getBillboard(1)->setColour(color*0.6); mHaloSet->getBillboard(2)->setColour(color); }LensFlare.material
From Ogre Wiki
material lensflare/halo { technique { pass { ambient 1 1 1 diffuse 1 1 1 lighting off depth_write off scene_blend add texture_unit { texture lensflare6.jpg } } } } material lensflare/burst { technique { pass { ambient 1 1 1 diffuse 1 1 1 lighting off depth_write off scene_blend add texture_unit { texture lensflare5.jpg } } } }
Type Position Scale
Main d 1
halo d/2 1/2
burst d/3 1/4
halo d/5 1
burst -d/2 1/2
halo -d/4 1/4
burst -d/5 1/4
LensFlare *lensflare;
bool frameStarted(const FrameEvent& evt) { .. .. lensflare->update(); }
CreateScene(void) { ... ... lensflare = new LensFlare(Vector3(0,10,0),mCamera, mSceneMgr); }
此代码还需要一个专门的material 。
LensFlare *lensflare;
bool frameStarted(const FrameEvent& evt)
{
..
..
lensflare->update();
}
CreateScene(void)
{
...
...
lensflare = new LensFlare(Vector3(0,10,0),mCamera, mSceneMgr);
}
源文件