2011-08-26 110 views
4

我正在实施一个阴影映射技术的变体,但我(想)正遭受精确度损失。精确度损失与未投影和重新投影

这里是我做的:

  • 我画我的场景从eyeposition填补了深度缓冲
  • 我unproject使用gluUnproject
  • 这点我使用gluProject我lightsource作为视点重新投影这些点
  • 我然后在我所有的三角形环,这些项目从我lightsource为视点

- >对于与三角形重叠的点(从第一步开始),我会比较深度。我将三角形像素处的内插深度与步骤2中重新投影的深度进行比较,如果三角形更接近,则将其映射到阴影中。

我使用重心坐标来在不规则位置插入深度。这意味着将三个浮点值比较为零,比较两个浮点数以查看哪一个更小,..我在所有比较中使用了偏差而没有任何大的影响(eps = 0.00001)

该算法运行良好,但我仍然有一些文物,我认为这些可以归因于un-and reprojecting。这可以吗?

我正在使用透视投影,我的near = 1.0和我的far = 20.0。 我能做些什么来改善这一点?

我很乐意展示一些代码,但它有很多。那么让我们先看看有什么建议。

Artifact http://img849.imageshack.us/img849/4420/artifactk.png

我读我的像素和unproject这样:

//Get the original pixels 
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[0]); 
glReadPixels(0, 0,800, 300, GL_DEPTH_COMPONENT,GL_FLOAT, BUFFER_OFFSET(0)); 

glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[1]); 
glReadPixels(0, 300, 800, 300, GL_DEPTH_COMPONENT,GL_FLOAT, BUFFER_OFFSET(0)); 

//Process the first batch of pixels 
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[0]); 
GLfloat *pixels1 = (GLfloat*)glMapBufferARB(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); 
processPixels(pixels1, lightPoints, modelview, projection, viewport, 0); 

//Process the second batch of pixels 
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[1]); 
GLfloat *pixels2 = (GLfloat*)glMapBufferARB(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); 
processPixels(pixels2, lightPoints, modelview, projection, viewport, 1); 

//Unamp buffers and restore default buffer 
glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pboIds[0]); 
glUnmapBuffer(GL_PIXEL_PACK_BUFFER); 

glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pboIds[1]); 
glUnmapBufferARB(GL_PIXEL_PACK_BUFFER); 

glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); 

//Projecting the original points to lightspace 
glLoadIdentity(); 
gluLookAt(light_position[0], light_position[1], light_position[2], 0.0,0.0,0.0,0.0,1.0,0.0); 

//We get the new modelview matrix - Lightspace 
glGetDoublev(GL_MODELVIEW_MATRIX, modelview); 

//std::cout <<"Reprojecting" << std::endl; 
GLdouble winX, winY, winZ; 
Vertex temp; 
//Projecting the points into lightspace and saving the sample points 
for(vector<Vertex>::iterator vertex = lightPoints.begin(); vertex != lightPoints.end(); ++vertex){ 
    gluProject(vertex->x, vertex->y, vertex->z,modelview, projection, viewport, &winX, &winY, &winZ); 
    temp.x = winX; 
    temp.y = winY; 
    temp.z = winZ; 
// std::cout << winX << " " << winY << " " << winZ << std::endl; 
    samplePoints.push_back(temp); 
} 

我的深度缓冲是24位,这是我无法改变的AFAIK(的ATI Radeon HD4570,我使用GLUT) 。

我比较我的深度:

if(rasterizer.interpolateDepth(A, B, C, baryc) < sample->z - 0.00001*sample->z){ 
       stencilBits[(((int)sample->y*800 +(int)sample->x)) ] = 1; 

都是浮动。

浮动应该enouhg精密顺便说一句,在论文中,我基于自己,他们也使用浮动。 }

+0

你如何比较你的浮动? –

+0

您可以在未投影之前和之后打印出您母校的值。应该可以告诉他们失去了多少准确性。 –

+0

让我确定我理解你的算法。你渲染场景。然后您将深度缓冲区读回到CPU。然后,对于每个像素,您可以调用gluUnproject。然后,你用不同的投影矩阵调用gluProject。如果这是你的算法(我希望它不是),那么我们需要看看你是如何读取深度缓冲区的。但最终,我不明白这将如何实际工作。 –

回答

0

夫妇的建议: - 实现正阴影映射,而无需CPU的事情第一 - 非常,非常仔细地阅读了OpenGL管道的数学,并确保你得到一切正常,包括四舍五入 - 你说内插深度。这听起来很错误 - 你不能直线插入深度(你可以深度平方,但我不认为你是这样做的)