PDA

View Full Version : Depth peeling, how can I get also the proper final depth component?



elect
10-16-2013, 06:30 AM
Hi,

I successfully implemented the depth peeling in Jogl using modern OpenGL. I understood deeply most of the process except the blend step.

However I need to center my scene on a specific user action. This requires read the window z coordinate.

The problem is that the depth peeling just copy at the end the result in terms of color from a texture to the (back) framebuffer, depth values arent taken in account... In fact I get always 1.0 as window Z (clear depth value) if I try to retrieve the depth value at a specific mouse coordinate...

The core part is the following


private void renderDepthPeeling(GL3 gl3) {
/**
* (1) Initialize min depth buffer.
*/
gl3.glBindFramebuffer(GL3.GL_FRAMEBUFFER, colorBlenderFboId[0]);
gl3.glDrawBuffer(GL3.GL_COLOR_ATTACHMENT0);

gl3.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl3.glClear(GL3.GL_COLOR_BUFFER_BIT | GL3.GL_DEPTH_BUFFER_BIT);

gl3.glEnable(GL3.GL_DEPTH_TEST);

dpInit.bind(gl3);
{
gl3.glUniform1f(dpInit.getAlphaUnLoc(), opacity);

drawModel(gl3);
}
dpInit.unbind(gl3);

/**
* (2) Depth peeling + blending.
*/
int layersNumber = (passesNumber - 1) * 2;

for (int layer = 1; layer < layersNumber; layer++) {

int currentId = layer % 2;
int previousId = 1 - currentId;

gl3.glBindFramebuffer(GL3.GL_FRAMEBUFFER, fboId[currentId]);
gl3.glDrawBuffer(GL3.GL_COLOR_ATTACHMENT0);

gl3.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl3.glClear(GL3.GL_COLOR_BUFFER_BIT | GL3.GL_DEPTH_BUFFER_BIT);

gl3.glDisable(GL3.GL_BLEND);

gl3.glEnable(GL3.GL_DEPTH_TEST);
{
dpPeel.bind(gl3);
{
gl3.glActiveTexture(GL3.GL_TEXTURE0);
gl3.glBindTexture(GL3.GL_TEXTURE_RECTANGLE, depthTextureId[previousId]);
gl3.glUniform1i(dpPeel.getDepthTexUnLoc(), 0);
{
gl3.glUniform1f(dpPeel.getAlphaUnLoc(), opacity);
drawModel(gl3);
}
gl3.glBindTexture(GL3.GL_TEXTURE_RECTANGLE, 0);
}
dpPeel.unbind(gl3);

gl3.glBindFramebuffer(GL3.GL_FRAMEBUFFER, colorBlenderFboId[0]);
gl3.glDrawBuffer(GL3.GL_COLOR_ATTACHMENT0);
}
gl3.glDisable(GL3.GL_DEPTH_TEST);

gl3.glEnable(GL3.GL_BLEND);
{
gl3.glBlendEquation(GL3.GL_FUNC_ADD);
gl3.glBlendFuncSeparate(GL3.GL_DST_ALPHA, GL3.GL_ONE, GL3.GL_ZERO, GL3.GL_ONE_MINUS_SRC_ALPHA);

dpBlend.bind(gl3);

gl3.glActiveTexture(GL3.GL_TEXTURE0);
gl3.glBindTexture(GL3.GL_TEXTURE_RECTANGLE, colorTextureId[currentId]);
gl3.glUniform1i(dpBlend.getTempTexUnLoc(), 0);
{
drawFullScreenQuad(gl3);
}
dpBlend.unbind(gl3);
}
gl3.glDisable(GL3.GL_BLEND);
}

/**
* (3) Final pass.
*/
gl3.glBindFramebuffer(GL3.GL_FRAMEBUFFER, 0);
gl3.glDrawBuffer(GL3.GL_BACK);
gl3.glDisable(GL3.GL_DEPTH_TEST);

dpFinal.bind(gl3);
{
gl3.glUniform3f(dpFinal.getBackgroundColorUnLoc(), 1.0f, 1.0f, 1.0f);

gl3.glActiveTexture(GL3.GL_TEXTURE0);
gl3.glBindTexture(GL3.GL_TEXTURE_RECTANGLE, colorBlenderTextureId[0]);
gl3.glUniform1i(dpFinal.getColorTexUnLoc(), 0);
{
drawFullScreenQuad(gl3);
}
gl3.glBindTexture(GL3.GL_TEXTURE_RECTANGLE, 0);
}
dpFinal.unbind(gl3);
}


What I am interested on should be in the first passage, where I do render the min depth buffer. I am thinking about just copying the texture linked at the depth_attachment into a temp texture. Then at the end, in the third passage, in the dpFinal program I could bind this temp texture too so that the fragment shader should just write into the Z component of the output fragment the right depth too..

I want to ask if this is feasible and in any case if you have a better idea about the solution

However here you find the whole code:

https://github.com/elect86/modern-jogl-examples/tree/master/modern-jogl-examples/src/depthPeeling/depthPeelingGL3