[Solved]Preparing for post processing in general

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
tank202
Competition winner
Posts: 40
Joined: Mon Jan 21, 2013 8:34 pm
Location: Lithuania, Kaunas

[Solved]Preparing for post processing in general

Post by tank202 »

Hello,
I want to post-process my game but dont know how to do it. Basicaly I know one thing - I need to have render target texture. Ok, I have it but what to do next? I've tried making hill plane mesh and parenting it to the camera that is constantly being moved by animators, but using this method I've got multiple problems:
1. My render target plane is inheriting only position of the camera, but I want it to inherit rotation too (As the camera tracks its target, my post-processing plane goes out of sight sometimes).
2. Even if my plane would inherit everything correctly it would be hard to customize plane size to fill the whole screen and with right proportions. Or maybe in other computers with different screen aspect ratio it would not cover all the screen at all.

Please give me couple of advices of how you normally do post processing planes and how to overcome that strange parenting issue.
Thank a lot in advance :D
Last edited by tank202 on Tue Jul 02, 2013 6:57 am, edited 1 time in total.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Preparing for post processing in general

Post by mongoose7 »

I don't think you mean "post-processing". With PP, you render the entire scene to a texture, so all problems of scene nodes are now in the past. Your aim, now, is to perform filtering on this texture while rendering it to the framebuffer. It is a 2D object and the problems are 2D problems.
rcalvin
Posts: 31
Joined: Tue Jan 08, 2013 1:58 am

Re: Preparing for post processing in general

Post by rcalvin »

I think he actually is talking about post-processing, but doesn't know how to re-render the texture that he had previously rendered to the texture. If that's the case, tank202, here is a ScreenQuad SceneNode that you can use. I'm pretty sure this comes courtesy of Mel, but I may be wrong.

Code: Select all

 
#pragma once
 
#include <irrlicht.h>
 
using namespace irr;
 
class CScreenQuadSceneNode : public scene::ISceneNode{
      core::aabbox3df aabb;               //An axis aligned bounding box. Actually not needed.
      video::SMaterial material;            //The material used to render the Scene Node
       video::S3DVertex2TCoords vertices[4];    //The vertices of the Scene Node.
                                    //Normally we wouldn't need more
                                    //than one set of UV coordinates.
                                    //But if we are to use the builtin materials, this is necesary
 
public:
       CScreenQuadSceneNode::CScreenQuadSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
       :ISceneNode(parent,mgr,id)
       {
          f32 shiftX,shiftY;
          core::dimension2d<u32> currentResolution;
 
/**Here we initialize the vertices of the screen Aligned quad*/
 
          currentResolution = mgr->getVideoDriver()->getScreenSize();
 
          aabb.reset(0,0,0);
 
          shiftX = 0;   //This small shift is necesary to compensate the texture sampling bias
          shiftY = 0;   //It avoids that our effect becomes too blurry.
 
         vertices[0] = video::S3DVertex2TCoords(
                  -1.0f,-1.0f,0.0f,
                  0.0f,0.0f,-1.0f,
                  video::SColor(255,255,255,255),
                  shiftX,1+shiftY,
                  shiftX,1+shiftY);
 
         vertices[1] = video::S3DVertex2TCoords(
                  1.0f,-1.0,0.0f,
                  0.0f,0.0f,-1.0f,
                  video::SColor(255,255,255,255),
                  1.0f+shiftX,1+shiftY,
                  1.0f+shiftX,1+shiftY);
 
         vertices[2] = video::S3DVertex2TCoords(
                  -1.0f,1.0,0.0f,
                  0.0f,0.0f,-1.0f,
                  video::SColor(255,255,255,255),
                  shiftX,shiftY,
                  shiftX,shiftY);
 
         vertices[3] = video::S3DVertex2TCoords(
                  1.0f,1.0f,0.0f,
                  0.0f,0.0f,-1.0f,
                  video::SColor(255,255,255,255),
                  1.0f+shiftX,shiftY,
                  1.0f+shiftX,shiftY);
 
/**Now we proceed to initialize the appropriate settings for the material we are going to use
We can alter these later, but for the time being, initializing then here will do no harm*/
 
         material.Lighting = false;                     //No need for lighting.
         material.MaterialType = video::EMT_LIGHTMAP_ADD;   //This will add both first and second textures :)
         material.BackfaceCulling=false;                  //not needed, but simplifies things
         setAutomaticCulling(scene::EAC_OFF);            //We don't need this scene
                                                //node to be culled because we render it in screen space.
      }
 
       CScreenQuadSceneNode::~CScreenQuadSceneNode()
       {
      }
 
      const core::aabbox3df& CScreenQuadSceneNode::getBoundingBox() const
      {
         return aabb;
      }
 
       void CScreenQuadSceneNode::OnRegisterSceneNode()
       {
         //This method is empty because it is best for us to render this scene node manually.
         //So, it is never really rendered on its own, if we don't tell it to do so.
      }
 
       void CScreenQuadSceneNode::render()
       {
         video::IVideoDriver* drv = getSceneManager()->getVideoDriver();
         core::matrix4 proj;
          u16 indices[] = {0,1,2,3,1,2};
          //A triangle list
 
         drv->setMaterial(material);
 
         drv->setTransform(video::ETS_PROJECTION, core::IdentityMatrix);
         drv->setTransform(video::ETS_VIEW, core::IdentityMatrix);
         drv->setTransform(video::ETS_WORLD, core::IdentityMatrix);
 
         drv->drawIndexedTriangleList(&vertices[0],4,&indices[0],2);
 
      }
 
       u32 CScreenQuadSceneNode::getMaterialCount()
       {
         return 1;   //There is only one material
      }
 
      video::SMaterial& CScreenQuadSceneNode::getMaterial(irr::u32 i)
      {
         return material;//We always return the same material, so there is no need for more.
      }
 
};
 

To use it, you just need to create an instance of it like so:

Code: Select all

 
CScreenQuadSceneNode* screenQuad = new CScreenQuadSceneNode(smgr->getRootSceneNode(),smgr,-1);
 
You will need to set it's texture to your RTT, and then set the material type to some Material type that you've defined for your shader:

Code: Select all

 
screenQuad->getMaterial(0).setTexture(0,rtt);
screenQuad->getMaterial(0).MaterialType = (E_MATERIAL_TYPE) yourMaterial;
 
And then when you render, you need to first render your scene to the RTT, then you can change the render target back to the framebuffer (or I guess another RTT, if you want to do another step), and render your Screen Quad:

Code: Select all

 
driver->setRenderTarget(rtt, true, true, SColor(0,0,0,255));
smgr->drawAll();
 
driver->setRenderTarget(ERT_FRAME_BUFFER, true, false, SColor(0,0,0,255));
screenQuad->render();
 
Please note, I don't really do this stuff very much, so it might not be wholly accurate! However, I think it shows the general idea, and I think it works :lol:
tank202
Competition winner
Posts: 40
Joined: Mon Jan 21, 2013 8:34 pm
Location: Lithuania, Kaunas

Re: Preparing for post processing in general

Post by tank202 »

Ok seems we have explanation for half of the problem, what about parenting on animator controled scene node? Or will i have to hard-code those animators myself?
rcalvin
Posts: 31
Joined: Tue Jan 08, 2013 1:58 am

Re: Preparing for post processing in general

Post by rcalvin »

Why do you need to parent anything? From what I understood in your original question, you were trying to line up a plane mesh in front of the camera which was being moved by animators. The thing is, you don't need to! I won't pretend to know how it works, like I said, I've only dabbled with Post Processing myself, but the ScreenQuad is drawn automatically so that it fills the screen when it's drawn. No need to line it up in front of the camera manually.
tank202
Competition winner
Posts: 40
Joined: Mon Jan 21, 2013 8:34 pm
Location: Lithuania, Kaunas

Re: Preparing for post processing in general

Post by tank202 »

Works like a charm :D Thanks friends for helping me out :D This is the most helping comunity I've ever seen.
Post Reply