(c++/OpenGL) Motionblur
Sorry but anything below a PS 2.0 will not work (They are restricted to 4 or less texture reads...). I doubt very much that this can work on a Geforce 4 unless you use some weird register combiner type thing or some fixed function effect.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Call of Duty did such an effect somehow (on my GF4), so it is possible
Does anyone know a bloom effect which should work on a GF4? At least I think that would look even better than a motion blur...
TheGameMaker you made a bloom as I see, but I guess it won't work on my graphic card again
Does anyone know a bloom effect which should work on a GF4? At least I think that would look even better than a motion blur...
TheGameMaker you made a bloom as I see, but I guess it won't work on my graphic card again
I'm not a native English speaker.
I'm trying to compile the motion blur shader code, using irrlicht 1.4, and I'm getting the following errors:
What could be the problem? Is it because this source code was compiled against irrlicht 1.3 and in 1.4 'irr::video::SMaterial' had a 'Textures' declaration?
Code: Select all
----- Build started: Project: motion blur test, Configuration: Debug Win32 ------
1>Compiling...
1>Motionblurmain.cpp
1>c:\documents and settings\XX\desktop\motion blur\motion blur test\motion blur test\postprocessmotionblur.h(115) : error C2039: 'Textures' : is not a member of 'irr::video::SMaterial'
1> c:\program files\irrlicht-1.4\include\smaterial.h(66) : see declaration of 'irr::video::SMaterial'
1>c:\documents and settings\XX\desktop\motion blur\motion blur test\motion blur test\postprocessmotionblur.h(116) : error C2039: 'Textures' : is not a member of 'irr::video::SMaterial'
1> c:\program files\irrlicht-1.4\include\smaterial.h(66) : see declaration of 'irr::video::SMaterial'
1>c:\documents and settings\XX\desktop\motion blur\motion blur test\motion blur test\postprocessmotionblur.h(121) : error C2039: 'Textures' : is not a member of 'irr::video::SMaterial'
1> c:\program files\irrlicht-1.4\include\smaterial.h(66) : see declaration of 'irr::video::SMaterial'
1>c:\documents and settings\XX\desktop\motion blur\motion blur test\motion blur test\motionblurmain.cpp(59) : warning C4305: 'argument' : truncation from 'double' to 'float'
1>Build log was saved at "file://c:\Documents and Settings\XX\Desktop\Motion blur\motion blur test\motion blur test\Debug\BuildLog.htm"
1>motion blur test - 3 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
-
- Posts: 86
- Joined: Thu Feb 14, 2008 7:30 pm
- Location: Portugal
sorry for the newbie question, but how did u fixed it
i am having the same problem, but since i am new to irr and just restarted programing recently, i am having some trouble understanding the api reference on irr web site on the changes made to the smaterial instruction.
i can't find what do i have to use to replace the old line
Material.Textures[0]=rt0;
i know Textures[0] no longer exist but i can't find what is replacing it or how to do it :/
i am having the same problem, but since i am new to irr and just restarted programing recently, i am having some trouble understanding the api reference on irr web site on the changes made to the smaterial instruction.
i can't find what do i have to use to replace the old line
Material.Textures[0]=rt0;
i know Textures[0] no longer exist but i can't find what is replacing it or how to do it :/
-
- Posts: 86
- Joined: Thu Feb 14, 2008 7:30 pm
- Location: Portugal
code updated
Followed the threads and tested the code. Just to paste the working code with the latest irrlicht:
#ifndef __POST_PROCESS_EFFECT_MOTION_BLUR__
#define __POST_PROCESS_EFFECT_MOTION_BLUR__
#include "irrlicht.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class PPE_MotionBlur_callback: public video::IShaderConstantSetCallBack
{
public:
float strength;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("strength", reinterpret_cast<f32*>(&strength),1);
int var0=0;
services->setPixelShaderConstant("texture1", (float*)(&var0), 1);
int var1=1;
services->setPixelShaderConstant("texture2", (float*)(&var1), 1);
}
};
class IPostProcessMotionBlur : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;//the material used with shader
video::SMaterial Accum;//a simple diffuse material..
video::ITexture* next; //the rendertarget
video::ITexture* prev; //the rendertarget
video::ITexture* accum; //the rendertarget
int mat;
PPE_MotionBlur_callback* callback;
IPostProcessMotionBlur(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}
void initiate(unsigned int sizeW,unsigned int sizeH,float strength,scene::ISceneManager* smgr)
{
static stringc vertShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragShader =
"uniform sampler2D texture1;"
"uniform sampler2D texture2;"
"varying vec2 vTexCoord;"
"uniform float strength;"
"void main()"
"{"
" gl_FragColor = mix( texture2D( texture1, vTexCoord ), texture2D( texture2, vTexCoord ), vec4( strength,strength,strength,strength) );"
"}";
static stringc fragShader2 =
"uniform sampler2D texture1;"
"varying vec2 vTexCoord;"
"void main()"
"{"
" gl_FragColor =texture2D( texture1, vTexCoord );"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
callback= new PPE_MotionBlur_callback();
callback->strength=strength;
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
Accum.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader2.c_str(), "main", video::EPST_PS_1_1,
NULL, (video::EMT_SOLID)
);
next = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW,sizeH));
prev = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW,sizeH));
accum = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0,next);
Material.setTexture(1,prev);
Accum.Wireframe = false;
Accum.Lighting = false;
Accum.setTexture(0,accum);
}
virtual void OnPreRender(){}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver(); //Fills Next
driver->setRenderTarget(next, true, true, video::SColor(0,0,0,0));
SceneManager->drawAll();
driver->setRenderTarget(accum, true, true, video::SColor(0,0,0,0)); //Combine Next&prev in accum
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
driver->setRenderTarget(prev, true, true, video::SColor(0,0,0,0)); //Write back accum into prev
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
virtual void renderFinal()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
u16 indices[] = {0,1,2,3,4,5};
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
#endif
#ifndef __POST_PROCESS_EFFECT_MOTION_BLUR__
#define __POST_PROCESS_EFFECT_MOTION_BLUR__
#include "irrlicht.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class PPE_MotionBlur_callback: public video::IShaderConstantSetCallBack
{
public:
float strength;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("strength", reinterpret_cast<f32*>(&strength),1);
int var0=0;
services->setPixelShaderConstant("texture1", (float*)(&var0), 1);
int var1=1;
services->setPixelShaderConstant("texture2", (float*)(&var1), 1);
}
};
class IPostProcessMotionBlur : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;//the material used with shader
video::SMaterial Accum;//a simple diffuse material..
video::ITexture* next; //the rendertarget
video::ITexture* prev; //the rendertarget
video::ITexture* accum; //the rendertarget
int mat;
PPE_MotionBlur_callback* callback;
IPostProcessMotionBlur(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}
void initiate(unsigned int sizeW,unsigned int sizeH,float strength,scene::ISceneManager* smgr)
{
static stringc vertShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragShader =
"uniform sampler2D texture1;"
"uniform sampler2D texture2;"
"varying vec2 vTexCoord;"
"uniform float strength;"
"void main()"
"{"
" gl_FragColor = mix( texture2D( texture1, vTexCoord ), texture2D( texture2, vTexCoord ), vec4( strength,strength,strength,strength) );"
"}";
static stringc fragShader2 =
"uniform sampler2D texture1;"
"varying vec2 vTexCoord;"
"void main()"
"{"
" gl_FragColor =texture2D( texture1, vTexCoord );"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
callback= new PPE_MotionBlur_callback();
callback->strength=strength;
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
Accum.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader2.c_str(), "main", video::EPST_PS_1_1,
NULL, (video::EMT_SOLID)
);
next = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW,sizeH));
prev = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW,sizeH));
accum = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0,next);
Material.setTexture(1,prev);
Accum.Wireframe = false;
Accum.Lighting = false;
Accum.setTexture(0,accum);
}
virtual void OnPreRender(){}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver(); //Fills Next
driver->setRenderTarget(next, true, true, video::SColor(0,0,0,0));
SceneManager->drawAll();
driver->setRenderTarget(accum, true, true, video::SColor(0,0,0,0)); //Combine Next&prev in accum
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
driver->setRenderTarget(prev, true, true, video::SColor(0,0,0,0)); //Write back accum into prev
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
virtual void renderFinal()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
u16 indices[] = {0,1,2,3,4,5};
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
#endif
dude check out how they do it in garry's mod, you dont need shaders and its pretty convincing
YOU ONLY NEED 1 or 2 RTT
render scene
set render target to "copiedLastFrame"
draw "lastScene" with a wuad onto the screen using some alpha value like 0.1
set render target to "lastScene" and copy "copiedLastFrame" into it
now the last scene amasses the frames before it...
YOU ONLY NEED 1 or 2 RTT
render scene
set render target to "copiedLastFrame"
draw "lastScene" with a wuad onto the screen using some alpha value like 0.1
set render target to "lastScene" and copy "copiedLastFrame" into it
now the last scene amasses the frames before it...
I edited it a bit, the following works with irrlicht 1.6.
However I'm also getting that wierd ghosting effect.
Would really appreciate it if a more pro kind of guy came around and helped us out with the ghosting issue. I really like the idea of being able to use motion blur with ease in my irrlicht apps but with the ghosting it's just not going to happen right now...
Hybrid or someone? Help?
However I'm also getting that wierd ghosting effect.
Would really appreciate it if a more pro kind of guy came around and helped us out with the ghosting issue. I really like the idea of being able to use motion blur with ease in my irrlicht apps but with the ghosting it's just not going to happen right now...
Hybrid or someone? Help?
Code: Select all
#ifndef __POST_PROCESS_EFFECT_MOTION_BLUR__
#define __POST_PROCESS_EFFECT_MOTION_BLUR__
#include "irrlicht.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class PPE_MotionBlur_callback: public video::IShaderConstantSetCallBack
{
public:
float strength;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("strength", reinterpret_cast<f32*>(&strength),1);
int var0=0;
services->setPixelShaderConstant("texture1", (float*)(&var0), 1);
int var1=1;
services->setPixelShaderConstant("texture2", (float*)(&var1), 1);
}
};
class IPostProcessMotionBlur : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;//the material used with shader
video::SMaterial Accum;//a simple diffuse material..
video::ITexture* next; //the rendertarget
video::ITexture* prev; //the rendertarget
video::ITexture* accum; //the rendertarget
int mat;
PPE_MotionBlur_callback* callback;
IPostProcessMotionBlur(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}
void initiate(unsigned int sizeW,unsigned int sizeH,float strength,scene::ISceneManager* smgr)
{
static stringc vertShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragShader =
"uniform sampler2D texture1;"
"uniform sampler2D texture2;"
"varying vec2 vTexCoord;"
"uniform float strength;"
"void main()"
"{"
" gl_FragColor = mix( texture2D( texture1, vTexCoord ), texture2D( texture2, vTexCoord ), vec4( strength,strength,strength,strength) );"
"}";
static stringc fragShader2 =
"uniform sampler2D texture1;"
"varying vec2 vTexCoord;"
"void main()"
"{"
" gl_FragColor =texture2D( texture1, vTexCoord );"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
callback= new PPE_MotionBlur_callback();
callback->strength=strength;
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
Accum.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader2.c_str(), "main", video::EPST_PS_1_1,
NULL, (video::EMT_SOLID)
);
next = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
prev = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
accum = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0,next);
Material.setTexture(1,prev);
Accum.Wireframe = false;
Accum.Lighting = false;
Accum.setTexture(0,accum);
}
virtual void OnPreRender(){}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver(); //Fills Next
driver->setRenderTarget(next, true, true, video::SColor(0,0,0,0));
SceneManager->drawAll();
driver->setRenderTarget(accum, true, true, video::SColor(0,0,0,0)); //Combine Next&prev in accum
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
driver->setRenderTarget(prev, true, true, video::SColor(0,0,0,0)); //Write back accum into prev
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
virtual void renderFinal()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
u16 indices[] = {0,1,2,3,4,5};
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
#endif