2011-08-26 106 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管道的數學,並確保你得到一切正常,包括四捨五入 - 你說內插深度。這聽起來很錯誤 - 你不能直線插入深度(你可以深度平方,但我不認爲你是這樣做的)