我用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缓冲值=(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 (清晰的深度值)。
你能解释一下这种行为吗?
答案 0 :(得分:1)
所以我认为计算是:Z缓冲值=(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(…)
视为身份转换,即通过它保持不变。