0

I have rendered a depth map to a framebuffer in the following way:

// the framebuffer
glGenFramebuffers(1, &depthMapFBO);

// completion: attacching a texture
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, SCR_WIDTH, SCR_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);  // i.e. allocate memory, to be filled later at rendering

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

// bind framebuffer and attach depth texture
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
glDrawBuffer(GL_NONE);  // i.e. explicitly tell we want no color data
glReadBuffer(GL_NONE);  // i.e. explicitly tell we want no color data
glBindFramebuffer(GL_FRAMEBUFFER, 0);

Note the use of GL_DEPTH_COMPONENT32F because I want a high precision.

Now I want to put the values stored in the depth buffer of the framebuffer into an array, preserving the precision. How to do so? Here is what I had in mind:

glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); 
glClear(GL_DEPTH_BUFFER_BIT);
[ render the scene to framebuffer]
GLfloat * d= new GLfloat[conf::SCR_WIDTH * conf::SCR_HEIGHT];
glReadPixels(0, 0, conf::SCR_WIDTH, conf::SCR_HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, d);

for (int i{ 0 }; i < conf::SCR_HEIGHT; ++i) {
    for (int j{ 0 }; j < SCR_WIDTH; ++j) {
        std::cout << d[i * SCR_WIDTH + j] << " ";
    }
    std::cout << std::endl;
}
        

However, this always prints 0.956376. Why so? I know I still have to re-linearize the depths... but why is always printed a constant value, and how can I fix this? Furthermore, is my approach correct, with regards to the lossless retrieval of information? Thanks in advance.


The same thing happens with:

GLfloat * d= new GLfloat[conf::SCR_WIDTH * conf::SCR_HEIGHT * 4];
glBindTexture(GL_TEXTURE_2D, depthMap);
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, d);
genpfault
  • 51,148
  • 11
  • 85
  • 139
Lilla
  • 209
  • 3
  • 9
  • 1
    Could you try adding `glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT)` before `glReadPixels` and after your “render the scene to framebuffer”? It could be a synchronisation issue. – Andrea Mar 24 '22 at 22:05
  • So, I have tried "render to framebuffer"; glMemoryBarrier(...); GFloat d* ....; glReadPixels...; – Lilla Mar 24 '22 at 22:12
  • Now the program crashes with code -1073741819 @Andrea – Lilla Mar 24 '22 at 22:13
  • Is it possible that glGetTexImage is a better solution? I am having troubles even there, but perhaps it is of easier use? – Lilla Mar 24 '22 at 22:20
  • once you apply logrithimc depth you already lost the precision and F32 will not change anything what you need is [Linear depth buffer](https://stackoverflow.com/a/42515399/2521214) – Spektre Mar 25 '22 at 08:25
  • @Spektre It doesn't work, on screen I see the same artifacts and I still cannot pipe out the data from the framebuffer. – Lilla Mar 25 '22 at 08:43
  • @Spektre Also, why exactly I am losing the precision? – Lilla Mar 25 '22 at 08:52
  • @Leonardo because perspective projection is changing depth scale from linear to logarithmic and the process is loosing precision (because of math involved) those resulting "truncated" values are stored into depth buffer so no matter what you do with its pixelformat while still using 32bit floats or 24bit int or half floats it will not help. The remedy is store linear values for depth buffer (bypassing the logarithimc ones not recomputing it back!!!) or use depth buffer with higher preccission like 64 bit float (but that will still truncate just not as much) or both together. – Spektre Mar 25 '22 at 10:10
  • but note that even 64bit float will most likely not work as GL does not have any 64bit interpolators at least to my knowledge which is a big pain in the ass for high precision stuff like these [mandelbrot](https://stackoverflow.com/a/56197067/2521214) and [Atmospheric scattering](https://stackoverflow.com/q/25470493/2521214) – Spektre Mar 25 '22 at 10:11

0 Answers0