(c++/OpenGL) Motionblur

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

(c++/OpenGL) Motionblur

Post by TheGameMaker »

Hi,
I created some special effect nodes, and I want to make a little gift to you. So here it is: my Motionblur sceneNode!
It´s free, it´s simple it´s fast^^
some screens first(a pic says more than thousand words.. ya know)
Image
Image
Image

Its true Imagebased Motionblur, so its very fast.
It just blend the currend rendered image with the las few. (with just one 3Rendertargets!! so ther is NOT created a img for echa frame!!)
it has little effect on framerate (the testlevel normaly runs with about 180 FPS, with the MB applied at 130 at 1024x768)...
Its simple.. just do following:

Code: Select all


#include "PostProcessmotionblur.h"
// include the file(just like you named it^^)
    IPostProcessMotionBlur *MotionBlur = new IPostProcessMotionBlur(smgr->getRootSceneNode(), smgr, 666);
//create the node.. just somewhere in the code...

    MotionBlur->initiate(1024,512,0.85,smgr); //this sets the params: 
//(screenW,screenH,strength,smgr*) while screenW&H have to be the next llower power of two to the screensize.. strength should lay between 0.8&0.9.. just try it^^ 

	while(device->run()) 
	if (device->isWindowActive())
	{
	driver->beginScene(true, true, 0); //and change the renderloop
        MotionBlur->render();          //
	driver->setRenderTarget(0);// in fact this is the code that does the MB
	MotionBlur->renderFinal();   // pretty simple, you see??


		env->drawAll(); //and all the other blabla in the mainloop
	driver->endScene();

	}
and now the source that belongs into PostProcessMotionBlur.h



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->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.Textures[0]=next;
      Material.Textures[1]=prev;


      Accum.Wireframe = false;
      Accum.Lighting = false;
      Accum.Textures[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
sry.. i work with DevC++ so no DX, onl GLSL..
hope you like it!
greetz TGM
Last edited by TheGameMaker on Tue May 01, 2007 1:54 pm, edited 1 time in total.
jingquan
Posts: 222
Joined: Sun Aug 20, 2006 4:10 am
Contact:

Post by jingquan »

Oh, great effect. But do you have any idea how to do that in .NET?
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

I doubt its much diffrent from replacing all the -> with . :lol:

Great work, will try this out sometime. What do you mean by just one 3 rendertargers? Which is it one or 3 :P

PS: Nice to see it is PS1.1 yay
roxaz
Posts: 575
Joined: Tue Jan 23, 2007 8:35 pm
Location: LT

Post by roxaz »

good idea about motion blur. effect looks nice :)
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

Nice, keep it up! :D
Steel Style
Posts: 168
Joined: Sun Feb 04, 2007 3:30 pm
Location: France

Post by Steel Style »

You missed a #endif on your file.H, but Great Work!
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

roxaz wrote:good idea about motion blur. effect looks nice :)
Yes, good idea. Probably didn't get the idea from my own motion blur demo at all. :wink:
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post by TheGameMaker »

ok.. endif issue fixed..
Yes, good idea. Probably didn't get t ... all. Wink
well, its not my idea at all, i got an idea that should worke like this, but neer actualy did.. then I saw the ATI Rendermonkey Motionblur example, that worked more or less like I thought. Well.. a little later I got Motionblur^^
m_krzywy
Posts: 133
Joined: Sat Nov 04, 2006 2:05 pm

Post by m_krzywy »

have that error just including teh file...

323 Z:\irrlicht-1.2\include\ISceneNode.h overriding `virtual irr::s32 irr::scene::ISceneNode::getMaterialCount()'

Irrlicht 1.2, Dev C++

edit:

I //virtual u32 getMaterialCount(){return 1;} that line and it's workin but i dono if effect is the same ;)
Ico
Posts: 289
Joined: Tue Aug 22, 2006 11:35 pm

Post by Ico »

Don't comment it out. Just change the "u32" to "s32" (or other way around? Not sure atm... damn ;) ) in the file you got from this thread.
LLDD
Posts: 43
Joined: Fri May 11, 2007 9:50 am

Post by LLDD »

Ico wrote:Don't comment it out. Just change the "u32" to "s32" (or other way around? Not sure atm... damn ;) ) in the file you got from this thread.
I had to change it to s32 and it works fine now. Good job TheGameMaker :)
________
Teen Health Forums
Last edited by LLDD on Sun Feb 20, 2011 2:12 am, edited 1 time in total.
RhavoX
Posts: 33
Joined: Tue Jul 04, 2006 7:27 pm

Post by RhavoX »

With dev-cpp u can also do dx apps so if someone would point you in the right direction would u try to do that in dx? :P
Teh Uber-Pwner xD
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post by TheGameMaker »

no need for that... someone else already converted it for DX..
http://irrlicht.sourceforge.net/phpBB2/ ... c&start=15
thx to belfegor for his amount of time&work he spent on doing this!
besides I would be interested in a tutorial for using dx with DevC++, since its a problem many new users have.
(I personaly don´t like DX, nor do I want to develop Apps using it, since its more work to get them working on Linux)
Yarcanox
Posts: 33
Joined: Sat Apr 14, 2007 11:23 pm

Post by Yarcanox »

is GLSL version 1.3 good enough for this? I got a geforce 4 and using opengl I get "GLSL shader failed to compile"!
I'm not a native English speaker.
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post by TheGameMaker »

tbh I´m not shure if shader 1.3 is enought.. I only tested in on shader 2.0 systems.. sry (But I think this should be your problem indeed) :|
Post Reply