Отбор Frustum с матрицей вида
В шейдере GLSL мне нужно пропустить несколько патчей тесселяции, чтобы значительно повысить производительность. Эти патчи представляют собой треугольники с заданными мировыми координатами для каждой вершины. Однако, когда я конвертирую эти координаты в пространство просмотра для отбраковки усеченного конуса, возникает предел погрешности.
Это оригинальная местность.
Вот как ошибка влияет на это сверху.
Это крупный план раздела с грязью.
Эти ошибки происходят только вокруг верхней части экрана, а также по бокам и снизу. Вот код, который я использую, чтобы определить, должен ли я исключить треугольник (в GLSL).
bool inFrustum( vec3 p,vec3 q,vec3 r) {
vec4 Pclip = camera * vec4(p, 1.0f);
vec4 Qclip = camera * vec4(q, 1.0f);
vec4 Rclip = camera * vec4(r, 1.0f);
if(((-Pclip.w>Pclip.x&&-Qclip.w>Qclip.x&&-Rclip.w>Rclip.x)|| (Pclip.x>Pclip.w&&Qclip.x>Qclip.w&&Rclip.x>Rclip.w))||
((-Pclip.w>Pclip.y&&-Qclip.w>Qclip.y&&-Rclip.w>Rclip.y)||(Pclip.y>Pclip.w&&Qclip.y>Qclip.w&&Rclip.y>Rclip.w))||
((-Pclip.w>Pclip.z&&-Qclip.w>Qclip.z&&-Rclip.w>Rclip.z)||(Pclip.z>Pclip.w&&Qclip.z>Qclip.w&&Rclip.z>Rclip.w))){
return false;
}
else{
return true;
}
}
Буду очень признателен за любую помощь! Behemyth
1 ответ
В моем шейдере я использую следующее для отбраковки патчей:
bool visible(vec3 vert)
{
int clipoffset = 5; //a bit offset because of displacements
vec4 p = MVP*vec4(vert,1);
return !(( p1.x < -(p1.w+clipoffset))||
( p.x > (p.w+clipoffset))||
( p.y < -(p.w+clipoffset))||
( p.y > (p.w+clipoffset))||
( p.z < -(p.w+clipoffset))||
( p.z > (p.w+clipoffset)));
}
и это выглядит так сверху:
PS: я использую тесселяцию четырехугольников, поэтому я проверяю, находится ли одна из вершин в усечённой точке:
if( visible(inPos[0])||
visible(inPos[1])||
visible(inPos[2])||
visible(inPos[3]))
{
outt[0] = calcTessellationLevel(inPos[3],inPos[0]);
outt[1] = calcTessellationLevel(inPos[0],inPos[1]);
outt[2] = calcTessellationLevel(inPos[1],inPos[2]);
outt[3] = calcTessellationLevel(inPos[2],inPos[3]);
inn[1] = (outt[0]+outt[2])/2;
inn[0] = (outt[1]+outt[3])/2;
}
РЕДАКТИРОВАТЬ: В вашем коде может быть (и) ||
операторы вызвали проблему, попробуйте это без скобок после каждого второго утверждения:
if(S1||S2||S3||S4)
вместо
if((S1||S2)||(S3||S4))
РЕДАКТИРОВАТЬ:: хммм.... Я не посмотрел на дату, когда его спросили, не знаю, как я нашел его...OO