Can't get shader to work

Hi,
I came across the following code for a bloom shader:

  
uniform sampler2D bgl_RenderedTexture;  
  
void main()  
{  
   vec4 sum = vec4(0);  
   vec2 texcoord = vec2(gl_TexCoord[0]);  
   int j;  
   int i;  
  
   for( i= -4 ;i < 4; i++)  
   {  
        for (j = -3; j < 3; j++)  
        {  
            sum += texture2D(bgl_RenderedTexture, texcoord + vec2(j, i)*0.004) * 0.25;  
        }  
   }  
       if (texture2D(bgl_RenderedTexture, texcoord).r < 0.3)  
    {  
       gl_FragColor = sum*sum*0.012 + texture2D(bgl_RenderedTexture, texcoord);  
    }  
    else  
    {  
        if (texture2D(bgl_RenderedTexture, texcoord).r < 0.5)  
        {  
            gl_FragColor = sum*sum*0.009 + texture2D(bgl_RenderedTexture, texcoord);  
        }  
        else  
        {  
            gl_FragColor = sum*sum*0.0075 + texture2D(bgl_RenderedTexture, texcoord);  
        }  
    }  
}  

However, it doesn’t work with my testprogram. I use the ofxShader addon and load the shader into myShader. In the draw() function between myShader.setShaderActive(true) and myShader.setShaderActive(false) I draw some shapes. But I see nothing in the output window.
I’m not sure about

  
uniform sampler2D bgl_RenderedTexture;  

Do I have to pass something from my main app to the shader?
The only shader I’ve used so far is the blur shader I’ve found in this forum (which worked fine). So the whole thing is pretty new to me.

The code is from http://myheroics.wordpress.com/2008/09/04/glsl-bloom-shader/
It says it works fine on ATI cards, so maybe there is something ATI specific to it that doesn’t work on my Nvidia Card.

Haven’t played with these shaders in a while, but I think this one works. Of course you will need both ofxShader and ofxFboTexture. Ignore bloomShader::setParams, it’s a carry over from some experiments.

Instructions:

bloom.frag and bloom.vert go into bin/data/shaders.
add bloomShader.h and bloomShader.cpp to your project.
add bloomShader.h to include part of testApp.

  
#include "bloomShader.h"  

declare shader variable below in testApp class.

  
bloomShader sBloom;  

in setup function definition in testApp do something like:

  
sBloom.setup(ofGetWidth(), ofGetHeight());  

in draw function do:

  
sBloom.beginRender();  
//draw stuff here, either create function or just replace with   
// your own drawing code  
drawTarget();  
sBloom.endRender();  
//draw the actual FBO with shader  
sBloom.draw(0, 0, ofGetWidth(), ofGetHeight(), true);  

With the way OF handles shaders, the sampler2D (which is sampler2DRect in this case) is automatically passed. No need to worry. At least that’s what my experience has taught me. If someone knows any better feel free to school me.

Honestly there are better bloom shaders out there, but they are usually pretty complicated and require a good graphics card as well as multiple FBO’s. This one should work on most modern hardware at very little GPU cost.

Cheers.

bloom.zip

Thanks!
The difference between your attachment and the code I used before is sampler2d is replaced by sampler2dRect and texture2d is replaced by texture2dRect, right? Is this some ATI - Nvidia thing?

Btw: I had to add

  
#extension GL_ARB_texture_rectangle : enable  

to the shader in order to make it work.

sampler2D requires a power of two texture, ex: 512 x 512, and it’s texture coordinates are in the range 0 to 1.
sampler2DRect is a newer extension that enables any aspect texture, ex: 1024 x 768, and it’s texture coordinates go from 0 to height and width.
texture2D and texture2DRect are the same color lookup, just for their respective samplers.

[quote author=“hrb”]Btw: I had to add
Code:
#extension GL_ARB_texture_rectangle : enable
to the shader in order to make it work.[/quote]
Yeah, technically that should be in there, but I didn’t need it on my system.
GLSL is pretty confusing and hard to debug. Glad to pass on whatever knowledge I have.

If you feel like diving in, grab a copy of this book:
http://www.amazon.com/OpenGL-R-Shading-Language-2nd/dp/0321334892

It’s the GLSL canon. If you make anything cool, give it back to the community. Have fun.

I think the author of the shader above is astellato – thanks for making the code available.

I modified the code, and it’s working pretty well as a cheap-n-cheerful fake bloom shader.

Fragment shader: “bloom” is a uniform you pass in, in the range 0. (off) to 1. (full effect)

  
  
//#version 120  
#extension GL_EXT_gpu_shader4: enable  
#extension GL_ARB_texture_rectangle : enable  
  
// define our varying texture coordinates   
varying vec2 texCoord;  
uniform sampler2DRect tex0;  
uniform float bloom;  
  
  
void main()  
{  
    vec4 sum, dry;   
    int i, j;    
      
    for( i = -3 ;i <= 3; i++)    
    {    
        for (j = -3; j <= 3; j++)    
        {    
            sum += texture2DRect(tex0, texCoord + vec2(j, i) * 2.0) * 0.25;  // 2.0 = "radius step"  
        }    
    }    
      
    sum = sum * sum * 0.012; // 0.012 = arbitrary value   
    dry = texture2DRect(tex0, texCoord);  
    gl_FragColor = bloom * (1.0 - ((1.0 - sum) * (1.0 - dry))) +  ((1.0 - bloom) * dry); // screen mode blending  
   
}  
  

And a vertex shader for it:

  
  
#version 120  
  
varying vec2 texCoord;  
  
void main()  
{  
	texCoord = vec2(gl_MultiTexCoord0);  
	gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;  
}  
  

1 Like