Nvidia 260.19.44 gl_depth_component32f

Im trying to use GL_DEPTH_COMPONENT32F ( or GL_DEPTH32F_STENCIL8 for that matter ) instead of GL_DEPTH_COMPONENT24 to render my scene within an FBO. Ive tried both renderbuffers and texture attachments, but I have seen no visual differences between the two depth formats.

I am rendering a scene with very near and very far clip planes which causes a lot of z-fighting, so trying to use the higher bit precision to reduce the issue.

I have tried all the depth formats. The only format that gives me a different result is GL_DEPTH_COMPONENT16. I know the opengl spec says that GL_DEPTH_COMPONENT32F is a required format, so was wondering if anyone else has seen this problem?

Im running:
OpenGL renderer string: GeForce GTX 480/PCI/SSE2
OpenGL version string: 4.1.0 NVIDIA 260.19.44

Also tried this with the 260.19.12 driver.

While a 32b FP depth buffer gives a bit more depth resolution, if the ratio between your near and far buffers are greater than 10e6, you’ll encounter a lot of Z fighting at far distances. The 32F format still only uses the 0.0 to 1.0 range.

If you need an extremely large far plane, try increasing the near plane value. Otherwise, you’ll have to render the scene in Z-depth ranges.

See section 12.050:
http://www.opengl.org/resources/faq/technical/depthbuffer.htm

Right, I still expect z fighting, but what I would expect is:

  1. less z-fighting
  2. z-fighting at different distances, mainly bad z fighting at further distances

Following is a test program that should demonstrate what I am seeing. It simply sets up two FBOs, one with a 24bit depth buffer, and a second with a 32bit fp depth buffer. Then it draws two long rectangles that are nearly coplanar on each fbo. One drawn in white, the other drawn in black (black on top). The two fbo renderings are then blitted to the system fbo s.t. the 24bit fbo is on the left, and the 32bit fbo is on the right. What I expect is to see alternating black and white stripes at different depths for the two fbos. What I get is the exact same image for both. Near clip is at 0.0001 and far clip is at 1000.0 to force the issue.

Also attached is an image of the result. A second image is attached with the 32fp depth buffer switched to a 16bit depth buffer and near clip increased to 0.001. Using 16bit, I get the results I would expect.

BTW, change the format of one of the fbos to 16bit, and the expected occurs.



#include <GL/glew.h>
#include <GL/glut.h>
#include <stdio.h>

int window ;
int width = 600;
int height = 600;

float eye[] = { 0.0, -1.0, 10.0 };
float lookat[] = { 0.0, 100.0, 0.0 };
float up[] = { 0.0, 0.0, 1.0 };
enum swizzle { X=0, Y=1, Z=2 };
float fov = 60.0;

struct FBO
{
  GLuint id;           // FBO Handle
  GLuint colorID;      // Color Attachment Handle
  GLuint depthID;      // Depth Attachment Handle

  GLenum depth_format; // GL_DEPTH_COMPONENT24, ...

  FBO() : id(0), colorID(0), depthID(0) {}
} ;

FBO fbo24 ;
FBO fbo32 ;

float near_clip = 0.001 ;
float far_clip  = 1000.0 ;

void initFBO( FBO &fbo )
{
  if( fbo.id != 0 )
  {
    glDeleteRenderbuffers( 1, &fbo.colorID );
    glDeleteRenderbuffers( 1, &fbo.depthID );
    glDeleteFramebuffers( 1, &fbo.id );
    fbo.colorID = fbo.depthID = fbo.id = 0;
  }

  glGenFramebuffers( 1, &fbo.id );
  glBindFramebuffer( GL_FRAMEBUFFER, fbo.id );

  glGenRenderbuffers( 1, &fbo.colorID );
  glBindRenderbuffer( GL_RENDERBUFFER, fbo.colorID );
  glRenderbufferStorage( GL_RENDERBUFFER, GL_RGB, width, height );

  glGenRenderbuffers( 1, &fbo.depthID );
  glBindRenderbuffer( GL_RENDERBUFFER, fbo.depthID );
  glRenderbufferStorage( GL_RENDERBUFFER, fbo.depth_format, width, height );
  
  glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fbo.colorID );
  glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, fbo.depthID );
}

void init()
{
#define GLEW_STATIC 1
  glewInit() ;
 
  fbo24.depth_format = GL_DEPTH_COMPONENT24 ;
  fbo32.depth_format = GL_DEPTH_COMPONENT16 ;
  initFBO( fbo24 );
  initFBO( fbo32 );
  glBindFramebuffer( GL_FRAMEBUFFER, 0 );

  glClearColor( 0.5, 0.5, 1.0, 0.0 ) ;
  glEnable( GL_DEPTH_TEST );
}

void reshape( int w, int h )
{
  if( w != width || h != height )
  {
    width = w ;
    height = h;
    glViewport( 0, 0, width, height ) ;

    initFBO( fbo24 );
    initFBO( fbo32 );
  }

  glMatrixMode( GL_PROJECTION ) ;
  glLoadIdentity() ;
  gluPerspective( fov, (float)w/h, near_clip, far_clip ) ;

  glMatrixMode( GL_MODELVIEW ) ;
  glLoadIdentity() ;
  gluLookAt(  eye[X],    eye[Y],    eye[Z],
              lookat[X], lookat[Y], lookat[Z],
              up[X],     up[Y],     up[Z] ) ;
}

void drawTest()
{
  glColor3f( 1.0, 1.0, 1.0 );
  glBegin( GL_QUADS );
    glVertex3f( -20.0, 0.0,    0.0 );
    glVertex3f(  20.0, 0.0,    0.0 );
    glVertex3f(  20.0, 1000.0, 0.0 );
    glVertex3f( -20.0, 1000.0, 0.0 );
  glEnd();
  glColor3f( 0.0, 0.0, 0.0 );
  glBegin( GL_QUADS );
    glVertex3f( -20.0, 0.0,    0.1 );
    glVertex3f(  20.0, 0.0,    0.1 );
    glVertex3f(  20.0, 1000.0, 0.1 );
    glVertex3f( -20.0, 1000.0, 0.1 );
  glEnd();
}

void draw()
{
  glBindFramebuffer( GL_FRAMEBUFFER, 0);
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  glBindFramebuffer( GL_FRAMEBUFFER, fbo24.id );
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  drawTest();
  
  glBindFramebuffer( GL_READ_FRAMEBUFFER, fbo24.id );
  glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
  glBlitFramebuffer( 0, 0, width, height,
                     0, 0, width/2, height,
                     GL_COLOR_BUFFER_BIT, GL_NEAREST );

  glBindFramebuffer( GL_FRAMEBUFFER, fbo32.id ) ;
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
  drawTest();

  glBindFramebuffer( GL_READ_FRAMEBUFFER, fbo32.id );
  glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
  glBlitFramebuffer( 0, 0, width, height,
                     width/2, 0, width, height,
                     GL_COLOR_BUFFER_BIT, GL_NEAREST );

  glutSwapBuffers();
  glutPostRedisplay() ;
}


void key( unsigned char key, int x, int y )
{
  static float units = 1.0;
  
  switch( key )
  {
    case 'q' :
      glutDestroyWindow( window ) ;
      exit( 0 ) ;
      break ;
    case 'n' :
      near_clip += 0.001*units ;
      reshape( width, height );
      printf( "Near Clip = %f
", near_clip );
      break ;
    case 'N' :
      near_clip -= 0.001*units ;
      reshape( width, height );
      printf( "Near Clip = %f
", near_clip );
      break ;
    case 'f' :
      far_clip += 10.0*units ;
      reshape( width, height );
      printf( "Far Clip = %f
", far_clip );
      break ;
    case 'F' :
      far_clip -= 10.0*units ;
      reshape( width, height );
      printf( "Far Clip = %f
", far_clip );
      break ;
    case 'u' :
      units *= 10.0;
      break;
    case 'U' :
      units /= 10.0;
      break;
  }
  reshape( width, height ) ;
}

int main(int argc, char** argv)
{
  glutInit( &argc, argv ) ;
  glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH ) ;

  glutInitWindowSize( width, height ) ;
  glutInitWindowPosition( 200, 200 ) ;
  window = glutCreateWindow( "Depth Test" ) ;

  init() ;

  glutDisplayFunc( draw ) ;
  glutReshapeFunc( reshape ) ;
  glutKeyboardFunc( key ) ;

  glutMainLoop() ;
  return 0;
}


Sure looks like a bug to me. Same result when comparing DEPTH_COMPONENT24 against any of:

  • DEPTH_COMPONENT32
  • DEPTH_COMPONENT32F
  • DEPTH32F_STENCIL8

Even get the same with:

  • GL_DEPTH_COMPONENT32F_NV
  • GL_DEPTH32F_STENCIL8_NV

which I notice have different values than the core/ARB versions. GTX480 with 260.19.36 drivers here.

Probably should submit a bug report to NVidia (nvdeveloper.nvidia.com).

Thanks! Will submit the bug report.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.