Posted: Wed Aug 29, 2007 5:23 am
by BlindSide
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.
Posted: Wed Aug 29, 2007 11:11 am
by Yarcanox
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
Posted: Tue Sep 18, 2007 10:46 pm
by L1zb3th
it's nice, but, very fps intensive =/
Au Revoir ^^
Posted: Thu Feb 21, 2008 8:48 am
by hybrid
Yes, the material stuff changed over the last versions, you have to adapt to the layout of the version you use.
Posted: Fri Feb 22, 2008 11:19 pm
by jonnys
I fixed it. Thanks. One thing I want to know though, is this the most modern way to do motion blur or is this an old method? What are the most modern methods to do it(eg. Crysis' way)?
Posted: Sun Feb 24, 2008 4:33 pm
by vectorcorpse
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 :/
code updated
Posted: Tue Feb 26, 2008 9:28 pm
by muenalan
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
Posted: Sun Oct 04, 2009 7:24 pm
by stefbuet
Thanks for sharing the code
I got a problem.
The effect is working fine, however, I can see old rendered frames over my skybox like this :
When I move the camera, they're staying, but if I rotate the camera then they disapear progressively (alpha -> 0)
Posted: Tue Oct 06, 2009 9:37 pm
by devsh
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...
Posted: Mon Oct 19, 2009 7:20 pm
by Jallen
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?
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