我正在实现阴影映射技术的变体,但我(认为)正在遭受精度损失。
这是我的做法:
- 我从眼位绘制我的场景以填充深度缓冲区
- 我使用 gluUnproject 取消投影这些点
- 我使用 gluProject 将光源中的这些点重新投影为视点
- 然后我遍历我所有的三角形,将它们从我的光源转换为视点
-> 对于与三角形重叠的点(从第一步开始),我比较深度。我将三角形像素处的插值深度与我在步骤 2 中重新投影的深度进行比较,如果三角形更近,则它被映射到阴影中。
我使用重心坐标在不规则位置插入深度。这意味着将三个浮点值与零进行比较,比较两个 float 以查看哪个较小,..我对所有比较都使用了偏差,但没有任何大的影响(eps = 0.00001)
该算法运行良好,但我仍然有一些瑕疵,我认为这些可以归因于反投影和重新投影。可以这样吗?
我正在使用透视投影,我的 near = 1.0,我的 far = 20.0。 我可以做些什么来改善这一点?
我很乐意展示一些代码,但代码太多了。所以让我们先看看有什么建议。
Artifact http://img849.imageshack.us/img849/4420/artifactk.png
我以这种方式读取我的像素并取消投影:
//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;
两者都是 float 。
顺便说一句, float 应该足够精确,在论文中我基于他们也使用 float 。
最佳答案
关于c++ - 取消投影和重新投影的精度损失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7198839/