GLSL post process

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Xeus32
Posts: 20
Joined: Tue Mar 22, 2005 9:11 am
Location: Italy , Padua

GLSL post process

Post by Xeus32 »

I use glsl for post processing. Now i use only a black and white filtring.
I develop the shader with render monkey all work fine. When i use in irrlicht the shader faild to compile! Why?

to load shader and post process class i use this :
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=10865
I use Irrlicht 1.0

//vertex

uniform sampler2D Texture0;
uniform float viewport_inv_width;
uniform float viewport_inv_height;
varying vec2 texCoord;


void main(void)
{
vec2 P = sign( gl_Vertex.xy );
gl_Position = vec4( P, 0.0, 1.0 );
texCoord = P * 0.5 + 0.5;

}

//fragment

uniform sampler2D Texture0;
varying vec2 texCoord;

void main(void)
{
vec4 color = texture2D(Texture0,texCoord);
float intensity = color.r * 0.299 + color.g * 0.587 +color.b * 0.184 ;
gl_FragColor = vec4(intensity, intensity, intensity,color.a) ;
}
TNX

Xeus32
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I see nothing wrong with your shaders, and I had no problem getting them to compile and link from within Irrlicht if I put them into seperate files.

Travis
Xeus32
Posts: 20
Joined: Tue Mar 22, 2005 9:11 am
Location: Italy , Padua

Where is wrong?

Post by Xeus32 »

Where is wrong?
there's my code :oops:

Code: Select all


// Class automatically generated by Dev-C++ New Class wizard

#ifndef CSHADERCALLBACK_H
#define CSHADERCALLBACK_H


#include <irrlicht.h>
#pragma comment(lib, "Irrlicht.lib")
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;


/**
 * Chiamata per l'esecuzione di un fitro come shader
 */
class cMyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:

   float viewport_inv_width;
   float viewport_inv_height;

   virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
   {
      video::IVideoDriver* driver = services->getVideoDriver();

      services->setVertexShaderConstant("viewport_inv_width", reinterpret_cast<f32*>(&viewport_inv_width), 1);
      services->setVertexShaderConstant("viewport_inv_height", reinterpret_cast<f32*>(&viewport_inv_height), 1);
             
   }
};

#endif // CSHADERCALLBACK_H

Code: Select all

// Class automatically generated by Dev-C++ New Class wizard

#ifndef CBASEFILTER__H
#define CBASEFILTER__H


#include <irrlicht.h>
#include "cmyshadercallback.h" 
#pragma comment(lib, "Irrlicht.lib")
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;


/**
 * Filtro base per il post processing
 */
class CBaseFilter : public scene::ISceneNode
{

   core::aabbox3d<f32> Box;
   video::S3DVertex Vertices[6];

public:
   video::SMaterial Material;
   c8* vsFileName; // filename for the vertex shader
   c8* psFileName; // filename for the pixel shader

   int newMaterialType1;
   cMyShaderCallBack* mc;

   video::ITexture* rt0;
   int alto;
   int ancho;

public:

   CBaseFilter(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
      : scene::ISceneNode(parent, mgr, id)
   {
      Material.Wireframe = false;
      Material.Lighting = false;

      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);
   
      Box.reset(Vertices[0].Pos);
      for (s32 i=1; i<4; ++i)
         Box.addInternalPoint(Vertices[i].Pos);

      mc = new cMyShaderCallBack();

      video::IVideoDriver* driver = SceneManager->getVideoDriver();
      rt0 = driver->createRenderTargetTexture(core::dimension2d<s32>(800,600));
      setMaterialTexture(0, rt0);
   }


   virtual void OnPreRender()
   {
      if (IsVisible)
         //SceneManager->registerNodeForRendering(this);

      ISceneNode::OnPreRender();
   }


   virtual void render()
   {
      u16 indices[] = {0,1,2,3,4,5};
      video::IVideoDriver* driver = SceneManager->getVideoDriver();

      driver->setMaterial(Material);
      driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
      driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
   }


   virtual const core::aabbox3d<f32>& getBoundingBox() const
   {
      return Box;
   }

   virtual s32 getMaterialCount()
   {
      return 1;
   }

   virtual video::SMaterial& getMaterial(s32 i)
   {
      return Material;
   }   
}; 
#endif // CBASEFILTER__H

Code: Select all

void Game::InitPostProcess(void)
{
     
   video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices(); 
   //1)create of object
   myFilter = new CBaseFilter(smgr->getRootSceneNode(), smgr, 666);
   if(myFilter==NULL) 
   {
      printf("errore caricamento Filter");                   
   }
   
   //2)select shader
   myFilter->psFileName = "bw.vert";
   myFilter->vsFileName = "bw.frag";

   //3)create "new material shader" and associate with filter
   myFilter->newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
            myFilter->vsFileName,"vertexMain", video::EVST_VS_3_0,
            myFilter->psFileName, "pixelMain", video::EPST_PS_3_0,
            myFilter->mc, video::EMT_SOLID);

   myFilter->setMaterialType((video::E_MATERIAL_TYPE)myFilter->newMaterialType1);

   //4) pass the constant-variables to IShaderConstantSetCallBack
   myFilter->mc->viewport_inv_height=1/600;
   myFilter->mc->viewport_inv_width=1/800;

   myFilter->drop(); 



}

Code: Select all



        if( PostPocess==true)
        {
             driver->beginScene(true, true, video::SColor(0,100,100,100));
             driver->setRenderTarget(myFilter->rt0,true, true, video::SColor(0,0,0,255));
             smgr->drawAll();
             driver->setRenderTarget(0);
             myFilter->render();
             driver->endScene(); 
        }
        else
        {
             driver->beginScene(true, true, video::SColor(0,100,100,100));
             driver->setRenderTarget(0,true, true, video::SColor(0,0,0,255));
             smgr->drawAll();
             driver->endScene(); 
        }
        
     
[/quote]
TNX

Xeus32
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

You'll have to use the debugger to step into your code and see where it actually fails. The simplest thing that could cause problems is the inability to locate the files bw.vert and bw.frag. If the files cannot be loaded, it would be difficult to compile them.

As I said before, I had no problem compiling/linking the shader files with the following line.

Code: Select all

s32 newMaterialType1 = driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles( 
            "media/bw.vert", "main", video::EVST_VS_1_1, 
            "media/bw.frag", "main", video::EPST_PS_1_1, 
            0, video::EMT_SOLID); 
Oh, you could eliminate cMyShaderCallBack and just make CBaseFilter inherit from IShaderConstantSetCallback and implement the appropriate methods. Then you don't need to allocate the callback object on the heap, you just pass a pointer to the base filter [this] when creating the shader material.

Travis
Xeus32
Posts: 20
Joined: Tue Mar 22, 2005 9:11 am
Location: Italy , Padua

Post by Xeus32 »

Oh, you could eliminate cMyShaderCallBack and just make CBaseFilter inherit from IShaderConstantSetCallback and implement the appropriate methods. Then you don't need to allocate the callback object on the heap, you just pass a pointer to the base filter [this] when creating the shader material.
TNX for all
TNX

Xeus32
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Wait wait one obious mistake is having samplers in a vertex shader!!!!

this is ok for vertex texture fetches but thats beyond most uses esp a posprocessor since you dont need a texture to modify its vertices

its most likely saying this rescoure isnt accessible through this setup

rember that uniforms are like globals and still transfer across to the fragment shader, varyings are the only ones that have to be repeated in both shaders since they are interpolated per texel as they are generated only on a per vertex basis
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Now i use only a black and white filtring.
i would reccomend using the alpha channel for black and white beacuse you code seems hardwired and may not yield black and white in scenes with un predicatble colours, moreover the alpha channel method is faster than all these multiplies

Code: Select all

vec4 color = texture2D(Texture0,texCoord);
gl_FragColor =color.a;
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Xeus32

i have the same problem , so that i have changed SL to CG.

here is your shader program but with CG works fin with me.

Code: Select all

void Vmain( float4 position          : POSITION,             
            out float4 oPosition     : POSITION,            
            out float2 oTexCoord     : TEXCOORD)            
     {                                                     
           float2 P = sign( position.xy );                 
           oPosition = float4( P.x,-P.y ,0.0, 1.0 );       
           oTexCoord = P * 0.5 + 0.5;                      
     }                                                     

    

void Fmain(  float2 TexCoord  : TEXCOORD,              
             out float4 color     : COLOR,             
             uniform sampler2D txtr : texunit0)        
     {                                                    
            float4 col  = tex2D(txtr, TexCoord);          
            float intensity = col.r * 0.299 + col.g * 0.587 +col.b * 0.184 ; 
            color  = float4(intensity, intensity, intensity,col.a) ;                         
     }            
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

My mistake! i forgot to ask you Xeus32 if you have an ATI card, ATi card dont suppourt glsl in irrlicht
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

omaremad wrote:My mistake! i forgot to ask you Xeus32 if you have an ATI card, ATi card dont suppourt glsl in irrlicht
Omer:

i have Nvidia Geforce 5200 fx and also have the same problem, any explaination please?
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Ok i examined the sahder again and found another thing, irrlicht doesnt recoginise the varying for the texcoord (irrlicht does not set it via varyings but via opengl commands)

so we need to acess it via the predefined varaiables just like you did in the cg shader
: TEXCOORD
also we cant have samplers in vertex shaders for most cards

so to extract texcoord information we should use

Code: Select all

gl_TexCoord[0] = gl_MultiTexCoord0;
in the vertex shader

and use gl_TexCoord[0]
instead of texcoord.
so this
texture2D(Texture0,texCoord);
becomes this
texture2D(Texture0,gl_TexCoord[0] );

if there are still errors try adding brackest round the multiplies or use my method to get black and white
[/quote]
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

My mistake! i forgot to ask you Xeus32 if you have an ATI card, ATi card dont suppourt glsl in irrlicht
Funny, I'm using an ATI Radeon 9600 Pro and the shader compiled and linked just fine.
gfxstyler
Posts: 222
Joined: Tue Apr 18, 2006 11:47 pm

Post by gfxstyler »

wtf? i have a radeon 9600 mobility and it fails to compile :)
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

I think the mobility series is completely different to the desktop series.But it could also be a question of the drivers.
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

It is a question of drivers since all ati cards seem to run opengl assembler fine, the compiler is provided by each vednor is different and is included in the driver
Post Reply