Потеря точности с непроектированием и репроектированием - PullRequest
4 голосов
/ 26 августа 2011

Я реализую вариант техники картирования теней, но я (думаю) страдаю от потери точности.

Вот что я делаю:

  • Я рисую свою сцену из положения глаз, чтобы заполнить буфер глубины
  • Я отменяю эти точки, используя gluUnproject
  • Я перепроектировал эти точки из моего источника света в качестве точки зрения, используя gluProject
  • Затем я перебираю все мои треугольники, проецирую их из моего источника света как точку зрения

-> Для точек (из первого шага), которые пересекаются с треугольником, я сравниваю глубину. Я сравниваю интерполированную глубину в пикселе треугольника с глубиной, которую я перепроектировал на шаге 2, если треугольник ближе, он отображается в тени.

Я использую барицентрические координаты для интерполяции глубины в неправильном месте. Это означает сравнение трех значений с плавающей точкой с нулем, сравнение двух значений с плавающей точкой, чтобы увидеть, какое из них меньше, .. Я использовал смещение для всех сравнений без каких-либо значительных эффектов (eps = 0,00001)

Алгоритм работает хорошо, но у меня все еще есть некоторые артефакты, и я думаю, что они могут быть отнесены к un- и reprojecting. Может ли это быть?

Я использую перспективную проекцию, моя близость = 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;

оба являются поплавками.

Кстати, поплавки должны быть достаточно точными, в статье я основываюсь на том, что они также используют поплавки. }

Ответы [ 2 ]

0 голосов
/ 08 ноября 2011

Пара предложений: - сначала реализуйте обычное отображение теней без использования процессора - очень, очень внимательно прочитайте математику конвейера opengl и убедитесь, что вы все правильно, включая округление, - говорите, интерполируя глубину.это звучит очень неправильно - вы просто не можете линейно интерполировать глубину как есть (вы можете сделать квадрат глубины, но я не думаю, что вы это делаете)

0 голосов
/ 23 октября 2011

Попробуйте поместить дальний самолет еще дальше: http://www.codermind.com/files/small_wnear.gif

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...