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即可。
示例效果:
整个立方体发光
立方体一条边发光
选择整个立方体,选择立方体的一条边时发光的效果。