0

我用 glDepthTest 编写了一个代码,并尝试了解投影 Z 缓冲区值的公式是什么。

我运行这段代码:

  #define CUBE_SIDE_SIZE   512.0f
  #define Z_SIZE   -0.25f
  #define WINDOW_WIDTH 1024
  #define WINDOW_HEIGHT    768
  void init(void)
  {
   glViewport(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity(); 
   glOrtho(0,WINDOW_WIDTH,0,WINDOW_HEIGHT, -1, 1);
  }

  void display(void)
  {
   GLfloat readPixel;

   glClearColor(0.0,0.0,0.0,0.0);
   glClearDepth(0.8);   
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glEnable(GL_DEPTH_TEST);  
   glDepthFunc(GL_LESS);

   glBegin(GL_QUADS);

   glColor3f(1, 0, 0);

   glVertex3f(0, 0, Z_SIZE);
   glVertex3f(0, CUBE_SIDE_SIZE, Z_SIZE);
   glVertex3f(CUBE_SIDE_SIZE, CUBE_SIDE_SIZE, Z_SIZE);
   glVertex3f(CUBE_SIDE_SIZE, 0, Z_SIZE);
   glEnd();
   glDisable(GL_DEPTH_TEST);
   glFlush();
   glutSwapBuffers();
   glReadPixels(0,0,1.0,1.0,GL_DEPTH_COMPONENT, GL_FLOAT, &readPixel);
}

在这种情况下 readPixel 的值为 0.625,所以我认为计算是:
Z-buffer value = (farZ - Z_value) / (farZ - nearZ)
在我的情况下:

[1 - (-0.25)] / ]1 - (- 1)] = 1.25 / 2 = 0.625

但是当我进行这些更改时: 1. #define Z_SIZE 0.25f 2. glOrtho(0,WINDOW_WIDTH,0,WINDOW_HEIGHT, 0, 1);

我在 readPixel 中得到值 0.8,这就像深度测试失败,但如果我计算 Z 缓冲区值,它应该等于 (1 - 0.25) / (1 - 0) = 0.75,小于 0.8(清晰深度价值)。

你能解释一下这种行为吗?

4

1 回答 1

1

所以我认为计算是:Z-buffer value = (farZ - Z_value) / (farZ - nearZ)

没有。还有一个额外的分裂因素1/w。这意味着深度缓冲区值不遵循线性进展。虽然它们是单调的。

NDC坐标的计算如下

pos_view = ModelviewMatrix · vertex_position
pos_projected = ProjectionMatrix · pos_view
pos_clipped = clip_prmitive( pos_projected )
pos_NDC = pos_clipped.xyz / pos_clipped.w

pos_NDC.z 是您的深度缓冲区值。对于理解转换步骤的所有实际方法,您可以将clip_primitive(…)其视为身份转换,即通过它,事情不会改变。

于 2013-10-14T11:26:29.677 回答