Ogre 發光效果

Ogre 對單個物體使用 glow 效果


使用的資源:
1. glow.compositor
compositor Glow
{
technique
{
texture rt0 target_width target_height PF_A8R8G8B8
texture glowMap target_width target_height PF_A8R8G8B8
texture AtoB target_width target_height PF_A8R8G8B8

//Fetch scene contents.
target rt0
{
input previous
}

//Get scene rendered with 'Glow' scheme
target glowMap
{
input none
material_scheme glow

pass clear
{
}

pass render_scene
{
}
}

//Blur it along X.
target AtoB
{
input none

pass clear
{
}

pass render_quad
{
material GlowCompositorMat/GlowA
input 0 glowMap
}
}

//Blur along Y, add to original, and output.
target_output
{
input none
pass render_quad
{
material GlowCompositorMat/GlowB
input 0 rt0
input 1 AtoB
}
}
}
}

2. glow.cg

float4 GlowA_fp(
float2 uv: TEXCOORD0,
uniform sampler2D scene: register(s0),
uniform float4 invTexSize
//uniform float time
) : COLOR
#define RENDER_SCENE 1
#define BLUR_RADIUS 3
{
float4 colour = float4(0);
float blurSize = BLUR_RADIUS * invTexSize.x;

colour += tex2D(scene, float2(uv.x - 4.0*blurSize, uv.y)) * 1.0/25.0;
colour += tex2D(scene, float2(uv.x - 3.0*blurSize, uv.y)) * 2.0/25.0;
colour += tex2D(scene, float2(uv.x - 2.0*blurSize, uv.y)) * 3.0/25.0;
colour += tex2D(scene, float2(uv.x - blurSize, uv.y)) * 4.0/25.0;
colour += tex2D(scene, float2(uv.x, uv.y)) * 5.0/25.0;
colour += tex2D(scene, float2(uv.x + blurSize, uv.y)) * 4.0/25.0;
colour += tex2D(scene, float2(uv.x + 2.0*blurSize, uv.y)) * 3.0/25.0;
colour += tex2D(scene, float2(uv.x + 3.0*blurSize, uv.y)) * 2.0/25.0;
colour += tex2D(scene, float2(uv.x + 4.0*blurSize, uv.y)) * 1.0/25.0;

return colour;
}

float4 GlowB_fp
(
float2 uv: TEXCOORD0,
uniform sampler2D scene: register(s0),
uniform sampler2D blurX: register(s1),
uniform float4 invTexSize//,
//uniform float time
) : COLOR
{
float4 colour = float4(0);
float blurSize = BLUR_RADIUS * invTexSize.y;

colour += tex2D(blurX, float2(uv.x, uv.y - 4.0*blurSize)) * 1.0 / 25.0;
colour += tex2D(blurX, float2(uv.x, uv.y - 3.0*blurSize)) * 2.0 / 25.0;
colour += tex2D(blurX, float2(uv.x, uv.y - 2.0*blurSize)) * 3.0/25.0;
colour += tex2D(blurX, float2(uv.x, uv.y - blurSize)) * 4.0/25.0;
colour += tex2D(blurX, float2(uv.x, uv.y)) * 5.0/25.0;
colour += tex2D(blurX, float2(uv.x, uv.y + blurSize)) * 4.0/25.0;
colour += tex2D(blurX, float2(uv.x, uv.y + 2.0*blurSize)) * 3.0/25.0;
colour += tex2D(blurX, float2(uv.x, uv.y + 3.0*blurSize)) * 2.0/25.0;
colour += tex2D(blurX, float2(uv.x, uv.y + 4.0*blurSize)) * 1.0/25.0;

return tex2D(scene, uv) + colour;
}

RENDER_SCENE 是光圈的半徑,可以根據自己需要和效果進行設置。
後面的colour是設置光圈的權重和比例,也可自己進行調解設置。

3. glow.program


fragment_program GlowA_fp cg
{
source glow.cg
entry_point GlowA_fp

default_params
{
param_named_auto invTexSize inverse_texture_size 0
//param_named_auto time time_0_2pi 1
}

profiles ps_2_0 arbfp1
}

material GlowCompositorMat/GlowA
{
technique
{
pass
{
cull_hardware none
cull_software none
depth_func always_pass

fragment_program_ref GlowA_fp
{
}

texture_unit map
{
tex_coord_set 0
tex_address_mode clamp
filtering trilinear
}
}
}
}

fragment_program GlowB_fp cg
{
source glow.cg
entry_point GlowB_fp

default_params
{
param_named_auto invTexSize inverse_texture_size 0
param_named_auto time time_0_2pi 4
}

profiles ps_2_0 arbfp1
}

material GlowCompositorMat/GlowB
{
technique
{
pass
{
cull_hardware none
cull_software none
depth_func always_pass

fragment_program_ref GlowB_fp
{
}

texture_unit scene
{
tex_coord_set 0
tex_address_mode clamp
filtering trilinear
}

texture_unit map
{
tex_coord_set 0
tex_address_mode clamp
filtering trilinear
}
}
}
}


4. GlowMaterialListener.h

#ifndef GLOWMATERIALLISTENER_H__
#define GLOWMATERIALLISTENER_H__

#include
#include

class GlowMaterialListener : public Ogre::MaterialManager::Listener
{
protected:
Ogre::MaterialPtr mBlackMat;
public:
GlowMaterialListener()
{
mBlackMat =Ogre::MaterialManager::getSingleton().create("mGlowBlack","Internal");
mBlackMat->getTechnique(0)->getPass(0)->setDiffuse(0,0,0,0);
mBlackMat->getTechnique(0)->getPass(0)->setSpecular(0,0,0,0);
mBlackMat->getTechnique(0)->getPass(0)->setAmbient(0,0,0);
mBlackMat->getTechnique(0)->getPass(0)->setSelfIllumination(0,0,0);
}

Ogre::Technique *handleSchemeNotFound(unsigned short, const Ogre::String&schemeName, Ogre::Material*mat, unsigned short, const Ogre::Renderable*)
{
if (schemeName == "glow")
{
//LogManager::getSingleton().logMessage(">> adding glow to material:"+mat->getName());
return mBlackMat->getTechnique(0);
}
return NULL;
}
};

#endif //GLOWMATERIALLISTENER_H__

前面三個放到resource中,並在resources.cfg中加入glow的路徑。
後面一個放到作爲一個頭文件你的代碼中。

代碼中加入合成器:

#include"GlowMaterialListener.h"
...
{
CompositorManager::getSingleton().addCompositor(mCamera->getViewport(),"Glow");
CompositorManager::getSingleton().setCompositorEnabled(mCamera->getViewport(),"Glow", true);
GlowMaterialListener *gml = new GlowMaterialListener();
Ogre::MaterialManager::getSingleton().addListener(gml);
}
註釋:前面兩句是加入合成器,並設置是否渲染合成器到rendering中;後面是使用所設置的資源。

實踐中遇到的關鍵點 :
Glow效果的開啓和關閉:
CompositorManager::getSingleton().setCompositorEnabled(mCamera->getViewport(),"Glow", true);
在進行glow效果開啓時,設置上面最後一個參數爲“true”;
在進行glow效果關閉時,設置上面最後一個參數爲“false”; 

Glow效果隨着屏幕大小改變時如何設置:
Ogre::CompositorManager::getSingleton().removeCompositor(m_Camera->getViewport(),"Glow");
resizeCameraWindow();
Ogre::CompositorManager::getSingleton().addCompositor(m_Camera->getViewport(),"Glow");
Ogre::CompositorManager::getSingleton().setCompositorEnabled(m_Camera->getViewport(),"Glow", true);
步驟:首先去掉合成器,然後重置窗口大小,利用camera重新把合成器加上去。這種情況在改變窗口大小時調用,否則會出現渲染效果模糊的情況!

Ø Glow效果在具體使用時如果設置:
material->getTechnique(0)->setSchemeName("glow");
前面創建了glow的合成器後,只需要glow效果的材質中設置setSchemeName即可。

示例效果:

整個立方體發光


 立方體一條邊發光


選擇整個立方體,選擇立方體的一條邊時發光的效果。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章