(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.
trivtn
Posts: 132
Joined: Tue Jan 17, 2006 12:30 pm
Location: Viet Nam
Contact:

Re: (c++/OpenGL) Motionblur

Post by trivtn »

PostProcessSceneNode

Code: Select all

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;
    f32 index_tex[2];
   PPE_MotionBlur_callback()
   {
     index_tex[0] =0;
     index_tex[1] =1;
   }
  virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
  {
    video::IVideoDriver* driver = services->getVideoDriver();
    services->setVertexShaderConstant("strength", reinterpret_cast<f32*>(&strength),1);
    services->setPixelShaderConstant("texture1", reinterpret_cast<f32*>(&index_tex[0]),1);
    services->setPixelShaderConstant("texture2", reinterpret_cast<f32*>(&index_tex[1]),1);
   }
};
 
class IPostProcessMotionBlur : public scene::ISceneNode
{
 
public:
   core::aabbox3d<f32> Box;
   video::S3DVertex Vertices[4];//the vertices for the onscreenquad
   video::SMaterial Material[2];//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;
   //f32 index_tex[2];
   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); 
        }
 
    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[0].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)
        );
     Material[1].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[0].Wireframe = false;
      Material[0].Lighting = false;
      Material[0].setTexture(0,next);
      Material[0].setTexture(1,prev);
 
 
      Material[1].Wireframe = false;
      Material[1].Lighting = false;
      Material[1].setTexture(0,accum);
    }
 
  // virtual void OnPreRender(){}
 
   virtual void render() 
   {
      u16 indices[] = {0,1,2,0,2,3};
      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[0]);
      driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
      driver->drawIndexedTriangleList(Vertices, 4, indices, 2);
      
      driver->setRenderTarget(prev, true, true, video::SColor(0,0,0,0));        //Write back accum into prev
      driver->setMaterial(Material[1]);
      driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
      driver->drawIndexedTriangleList(Vertices, 4, indices, 2);
      //
      renderFinal();
   }
   
   virtual void renderFinal() 
   {
      
      video::IVideoDriver* driver = SceneManager->getVideoDriver();
      u16 indices[] = {0,1,2,0,2,3};
      driver->setRenderTarget(0);
      driver->setMaterial(Material[1]);
      driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
      driver->drawIndexedTriangleList(Vertices, 4, indices, 2);
   }
 
  virtual u32 getMaterialCount(){return 1;}
  virtual video::SMaterial& getMaterial(s32 i){return (Material[0]);}
  virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
and in the main loop :

Code: Select all

if (deevice->isWindowActive())
        {
            driver->beginScene(true, true, 0); //and change the renderloop
            MotionBlur->render();          //
            //myDriver->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();
        }
Work in Irrlicht-1.8 ! Hope this help !
There's something is fantastic, there's nothing is absolute.
trivtn
Posts: 132
Joined: Tue Jan 17, 2006 12:30 pm
Location: Viet Nam
Contact:

Re: (c++/OpenGL) Motionblur

Post by trivtn »

please replace :

Code: Select all

 next = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
     prev = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
     accum = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
with codes :

Code: Select all

 next = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH),"RT1",video::ECF_A16B16G16R16F);
     prev = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH),"RT2",video::ECF_A16B16G16R16F);
     accum = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH),"RT3",video::ECF_A16B16G16R16F);
to get full motionblur effect ! Hope this help !
There's something is fantastic, there's nothing is absolute.
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: (c++/OpenGL) Motionblur

Post by thanhle »

trivtn wrote:please replace :

Code: Select all

 next = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
     prev = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
     accum = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
with codes :

Code: Select all

 next = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH),"RT1",video::ECF_A16B16G16R16F);
     prev = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH),"RT2",video::ECF_A16B16G16R16F);
     accum = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH),"RT3",video::ECF_A16B16G16R16F);
to get full motionblur effect ! Hope this help !
Great stuff Trivtn!
This will come in handy when I need it.
trivtn
Posts: 132
Joined: Tue Jan 17, 2006 12:30 pm
Location: Viet Nam
Contact:

Re: (c++/OpenGL) Motionblur

Post by trivtn »

My PostProcessSceneNode (with MotionBlur, Invert and Water effects)
Image
Thanks TheGameMaker !
There's something is fantastic, there's nothing is absolute.
Post Reply