不投影和重投影的精度损失
Precision loss with unprojecting and reprojecting
我正在实现阴影映射技术的一种变体,但我(认为)正在遭受精度损失。
我是这样做的:
- 我从眼睛位置绘制场景以填充深度缓冲区 我使用gluUnproject取消这些点的投影
- 我使用gluProject 将这些点从我的光源重新投影为视点
- 然后我循环遍历所有的三角形,将它们从我的光源投影为视点
->对于与三角形重叠的点(从第一步开始),我比较深度。我将三角形像素处的插值深度与我在步骤2中重新投影的深度进行比较,如果三角形更接近,它将被映射到阴影中。
我使用重心坐标在不规则位置插入深度。这意味着将三个浮点数的值与零进行比较,比较两个浮点数,看看哪个更小,…我在所有的比较中都使用了偏差,没有任何大的影响(eps = 0.00001)
算法工作得很好,但我仍然有一些伪影,我认为这些可以归因于非和重投影。这可能吗?
我使用透视投影,我的近= 1.0,我的远= 20.0。我能做些什么来改善这一点?
我很乐意展示一些代码,但它相当多。让我们先看看有什么建议。
工件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位,我不能改变一个错误(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。}
试着把远平面放远一点:http://www.codermind.com/files/small_wnear.gif
几点建议:-首先在没有CPU的情况下实现常规阴影映射-非常非常仔细地阅读opengl管道数学,并确保你得到正确的一切,包括四舍五入-你说插值深度。这听起来非常错误-你只是不能线性插值深度(你可以深度平方,但我不认为你正在这样做)
相关文章:
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 正在将csv文件读取为双精度矢量
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何在C++中的同一函数中使用字符串和双精度
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 当使用比格式支持的精度更高的精度来显示数字时,会写出什么数据
- 如何计算具有指定类型的表达式的相对精度和绝对精度
- 如何打印boost多精度128位无符号整数
- 检查是否以特定精度给出双精度
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- C 字符串返回字符串的整数/双精度/长整型值
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 如何使双精度值的 C++ 和 C# 中的结果相同
- 使用浮点数和双精度数的非常小数字的数学
- 使用 Xcode 将双精度存储在数组C++中
- 为什么输出精度没有正确舍入?
- 在 C++ 中将双精度变量写入二进制文件
- 不投影和重投影的精度损失