PDA

View Full Version : Deferred Shading: depth pass



mdl13
02-13-2011, 05:45 PM
Hi all

I wasn't sure where to post this, since the topic is advanced but I am not an expert in OpenGL.

Anyways, here it goes.

I am working on a deferred shader and I am trying to get the depth pass working but so far I can't manage to draw in the screen with the frame buffer.

Here is the code:






void initFBO(int w, int h){

GLenum FBOstatus;

glActiveTexture(GL_TEXTURE0);

glGenTextures(1, &depthTexture);

glBindTexture(GL_TEXTURE_2D, depthTexture);


glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0 );

//create FBO
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);

glBindTexture(GL_TEXTURE_2D, depthTexture);
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthTexture, 0 );

FBOstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(FBOstatus != GL_FRAMEBUFFER_COMPLETE) {
printf("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO\n");
checkFramebufferStatus(FBOstatus);
}

glClear(GL_DEPTH_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}

void draw_depth(){
glBindTexture(GL_TEXTURE_2D, depthTexture);
glDepthMask(true);
glmDraw(model, GLM_NONE);
}

void bindFBO() {
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0); //Bad mojo to unbind the framebuffer using the texture
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glClear(GL_DEPTH_BUFFER_BIT);
//glColorMask(false,false,false,false);
glEnable(GL_DEPTH_TEST);
}
void setTextures() {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

//glColorMask(true,true,true,true);
glDisable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);
}
void display(void){

bindFBO();

glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glDisable(GL_BLEND);

glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
//glDepthFunc(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthRange(0.0, 1.0);

glDisable(GL_TEXTURE_2D);
glColor4f(1.0f,1.0f,1.0f,1.0f);
glClearColor(0.0f,0.0f,0.0f,1.0f);
//glClearDepth(1.0);
glColorMask(true,true,true,true);
//glDepthMask(true);


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0, 1.0, 0.1, 10000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 10.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);

setTextures();

draw_depth();

glutPostRedisplay();
glutSwapBuffers();
}

void init() {
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f,1.0f);
}

//Loads the model by calling the corresponding glm function
void loadModel(){

char file_path[200];
char filename[50];
std::cin >> filename;

strcpy(file_path,path);
strcat(file_path,filename);
model = glmReadOBJ(file_path);
}

int main (int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
width = 600;
height = 600;
glutInitWindowSize(width,height);
glutCreateWindow("Deferred Shading");
//glewInit();
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
cout << "glewInit failed, aborting." << endl;
exit (1);
}
cout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << endl;
cout << "OpenGL version " << glGetString(GL_VERSION) << " supported\n" << endl;

initFBO(width, height);
init();

//getting and loading the model
loadModel();
while(!model){
printf( "\nModel wasn't loaded. Try again.\n" );
loadModel();
}

glutDisplayFunc(display);

glutMainLoop();
return 0;
}



My guess is that either I am doing something wrong in the display function or it has something to do with the obj loader i am using, which is glm and rather old. It uses glBegin and glEnd to draw, but I am not sure if this should be done in another way.

Thanks

mdl13
02-13-2011, 06:20 PM
I am now displaying something but it is not what would be expected of a depth pass for deferred shading.
Does anyone has any idea?

Thanks

Alfonse Reinheart
02-13-2011, 06:39 PM
I've never implemented a deferred renderer, but as I understand the theory, you don't really do a "depth" pass. You record the depth as a part of the rest of the g-buffer rendering. It's simply a natural out-growth of the first part of the deferred stage.

Ilian Dinev
02-14-2011, 05:40 AM
Right before glCheckFramebufferStatus() :




glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);


But, in deferred rendering you need the g-buffer; so instead of 0 color textures, you need 2+.
You may do a depth-prepass with simplified shaders and disabled color-write, but the best speedup would rather be "anti-portals".

BionicBytes
02-14-2011, 04:13 PM
Anti- portals?
Can you elaborate please!?

Ilian Dinev
02-15-2011, 10:13 AM
Just a very-low-poly version of the scene; without normals/textures - just vec3 position per vertex. Shouldn't protrude or z-fight with the real scene objects. Aids HiZ/Zcull.
Can z-sort those triangles quickly for reverse-painters' algo;
Can use occlusion-queries a bit faster, too. (Or get even much faster occlusion-q results if you render into a smaller viewport).

Alfonse Reinheart
02-15-2011, 11:24 AM
Isn't one of the benefits of deferred rendering that you don't need to do that, since you only run the expensive fragment programs on exactly and only the visible samples?

Or are you trying to save the fillrate from writing a (potentially large) number of outputs?

nickels
02-15-2011, 03:33 PM
I found this reference useful when implementing deferred rendering:

Deferred rendering in Stalker (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter09.html)

I don't understand the use of a depth pass, sounds like a different algorithm... Do you have a reference for what you're up to?

Exactly, each pixel gets the full shader only once per light, no penalty for high depth complexity.

Works well with additive translucency effects like fire, light glow, etc... Never figured how to do lit transparency, though...

Also, since depth is certainly one of the things you will likely write to the gbuffer (you will use this later to get your world X,Y,Z pixel position), maybe that is what you are trying to visualize? Which is very difficult since the buffer is very nonlinear in z. You might need to scale the buffer nonlinearly to see anything that is in it. Most of the interesting values will be very near 1.0, I believe (or zero if I have forgotten)...

Ilian Dinev
02-17-2011, 05:14 PM
Or are you trying to save the fillrate from writing a (potentially large) number of outputs?
exactly.

NeXEkho
02-17-2011, 07:17 PM
There's a LOT of tricks you can do to reduce the required number of targets. Under my renderer, the shapes/normals are rendered in one pass and then in the next the diffuse/specular/emissive are drawn out. The emissive is then abused as an accumulation buffer for the lighting passes.