OGRE 实现光晕 LensFlare-镜头眩光

英文原文:http://www.ogre3d.org/wiki/index.php/Displaying_LensFlare

 

本教程和代码作者User:Sphinkie

 

翻译:痞子龙 http://blog.youkuaiyun.com/pizi0475

 

镜头光晕效应是在强光的视野内一个镜头出现时产生的光学效应。


 

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


 
Lensflare5.jpg

 
Lensflare6.jpg



在计算机上,这种效应可以在二维或三维渲染。

二维方法
在镜头前创建一架飞机 光晕将会在这架飞机上画出。

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

LensFlare.cpp

lensflare.material

 

 

 

 

LensFlare.h

From Ogre Wiki

Jump to: navigation, search
 /* ------------------------------------------------------------------------- */
 // 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

Jump to: navigation, search
/* ------------------------------------------------------------------------- */
 // 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

Jump to: navigation, search
 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);
}


源文件


评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值