Shaders, fbo and depth texture


#1

Hi all,

I have another question about writing a DoF shader with OF (MacOS X 10.8). I found this shader : http://artmartinsh.blogspot.fr/2010/02/glsl-lens-blur-filter-with-bokeh.html. I’dl like to use it in my OF program, but there’s something i miss because all what i get is a sad black screen.

If i understood, i need to draw my whole 3D scene to a fbo with depth texture. Then, once everything is drawn, i call my shader. I initialized the Fbo in this way :

  
ofFbo::Settings settings;          
settings.width = ofGetWidth();  
settings.height = ofGetHeight();  
settings.useDepth = true;  
settings.useStencil = true;  
settings.depthStencilAsTexture = true;      
fbo.allocate(settings);  

Before drawing, i enable depth test :

  
glEnable(GL_DEPTH_TEST);  

Then i draw my 3d elements in the fbo and finally i need to use my shader when i draw the Fbo on the screen, right ?

  
dofShader.setUniformTexture("bgl_RenderedTexture", fbo, 0);  
dofShader.setUniformTexture("bgl_DepthTexture", fbo.getDepthTexture(), 0);  
dofShader.setUniform1f("focus", focus);  
fbo.draw(0, 0);  

I got a black screen when i do this. So my questions :

* When i display the Fbo’s depth texture (fbo.getDepthTexture().draw(0, 0, ofGetWidth(), ofGetHeight())), depth is well displayed but far stuff are white and near stuff are dark, i wonder if it’s normal.

* The vert shader is :

  
void main()  
{  
    gl_FrontColor = gl_Color;  
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  
}  

Right ?

* Is my method the right one ? Is there another way to do it ? I found some examples but it was with OF 006 (and i’d like to stay on 007 with ofShader and ofFbo classes). Does someone found an example with OF 007 ? This would be, of course, totally amazing!

Thanks a lot !


#2

One quick thing to note is that if you’re drawing the depth texture from the FBO and things are either white or black, your depth texture is working, but your values are too high. OF has the OpenGL camera set up so that the Z values get big quickly, whereas when you’re drawing those values directly as colors 0 is black and 1 is white, so you’re getting what you’re expecting, which an image rendered with a 0.0 - 1.0 range. Try something like this for reading those values:

  
  
float LinearizeDepth(float zoverw)  
{  
	float n = 1.0; // camera z near  
	float f = 20000.0; // camera z far  
	return (2.0 * n) / (f + n - zoverw * (f - n));  
}  
  
  
uniform sampler2D depthImg;  
uniform float depthValModifier;  
  
void main()  
{  
	float depth = texture2D(depthImg, gl_TexCoord[0].xy).r;  
	depth = LinearizeDepth(depth) * depthValModifier;  
  
	gl_FragColor = vec4(depth, depth, depth, 1.0);  
}  
  


Depth of field effect in GL ES 2.0
#3

hi,
i work on a DOF to put on mesh
i tried with the same example of you,
i get the same black screen, i tried the function to normalise the depht value, but nothing
shader are not so complex, but really hard to debug with out consol are thing like that

uniform sampler2D bgl_RenderedTexture;
uniform sampler2D bgl_DepthTexture;

const float blurclamp = 3.0; // max blur amount
const float bias = 0.6; //aperture - bigger values for shallower depth of field
uniform float focus; // this value comes from ReadDepth script.
uniform float depthValModifier;

float LinearizeDepth(float zoverw)
{
float n = 1.0; // camera z near
float f = 20000.0; // camera z far
return (2.0 * n) / (f + n - zoverw * (f - n));
}

void main()
{

float aspectratio = 2048.0/768.0;
vec2 aspectcorrect = vec2(1.0,aspectratio);

float depth1 = texture2D(bgl_DepthTexture,gl_TexCoord[0].xy ).r;
depth1 = LinearizeDepth(depth1) * depthValModifier;

float factor = ( depth1 - focus );

vec2 dofblur = vec2 (clamp( factor * bias, -blurclamp, blurclamp ));
vec4 col = vec4(0.0);

col += texture2D(bgl_RenderedTexture, gl_TexCoord[0].xy);

col += texture2D(bgl_RenderedTexture, gl_TexCoord[0].xy + (vec2( 0.0,0.4 )*aspectcorrect) * dofblur);


#4

Hi !

Thanks for your answers :slight_smile: Joshua, i tried your shader and i have strange results. First, i guess i need to enable GL_DEPTH_TEST when i draw into the fbo to get its depth texture, then when i use the shader i need to disable GL_DEPTH_TEST ?

I disabled GL_DEPTH_TEST to use the shader and for 0. < depthValModifier < 1. the whole fbo gets fully from black to white (without elements drawn), then for depthValModifier > 1. i only have white.

If i enable GL_DEPTH_TEST to use the shader, it displayes elements which are very near the camera and depthValModifier changes background color (from black to white).

Any idea ? Thanks a lot…


#5

Did you guys had any more success getting this to work?


#6

I was having trouble accessing FBO depth in shaders, but I got it working eventually. Here’s a minimal example that is tested with GL2 and GL3. https://gist.github.com/kylemcdonald/bedfba64d4c8fa4010b282471ad59735