2016-11-30 4 views
0

Как я понимаю, в полигонах OpenGL обычно обрезаются в пространстве клипа и только эти треугольники (или части треугольников, если процесс отсечения их разделяет), которые выживают при сравнении с + - w. Это требует реализации алгоритма обрезки многоугольника, такого как Sutherland-Hodgman.Обрезание треугольников в пространстве экрана на пиксель

Я реализую свой собственный растеризатор процессора и на данный момент хотел бы избежать этого. У меня есть координаты вершин NDC (не действительно нормализован, так как я ничего не закрепил, поэтому позиции могут не находиться в диапазоне [-1, 1]). Я хотел бы интерполировать эти значения для всех пикселей и отображать только пиксели, координаты NDC которых попадают в [-1, 1] в размерах x, y и z. Затем я дополнительно выполнил проверку глубины.

Будет ли это работать? Если да, то будет выглядеть интерполяция? Могу ли я использовать формулу OpenGl spec (страница 427 14.9) для интерполяции атрибутов, как описано here? В качестве альтернативы, следует использовать формулу 14.10, которая используется для интерполяции глубины (z) для всех трех координат (я действительно не понимаю, почему там используется другой)?

Update: Я попытался интерполяцией значений NDC на пиксель двумя способами:

w0, w1, w2 являются барицентрические веса вершин.

1) float x_ndc = w0 * v0_NDC.x + w1 * v1_NDC.x + w2 * v2_NDC.x; float y_ndc = w0 * v0_NDC.y + w1 * v1_NDC.y + w2 * v2_NDC.y; float z_ndc = w0 * v0_NDC.z + w1 * v1_NDC.z + w2 * v2_NDC.z;

2) float x_ndc = (w0*v0_NDC.x/v0_NDC.w + w1*v1_NDC.x/v1_NDC.w + w2*v2_NDC.x/v2_NDC.w)/ (w0/v0_NDC.w + w1/v1_NDC.w + w2/v2_NDC.w); float y_ndc = (w0*v0_NDC.y/v0_NDC.w + w1*v1_NDC.y/v1_NDC.w + w2*v2_NDC.y/v2_NDC.w)/ (w0/v0_NDC.w + w1/w1_NDC.w + w2/v2_NDC.w); float z_ndc = w0 * v0_NDC.z + w1 * v1_NDC.z + w2 * v2_NDC.z;

Тест отсечение + глубина всегда выглядит следующим образом:

if (-1.0f < z_ndc && z_ndc < 1.0f && z_ndc < currentDepth && 1.0f < y_ndc && y_ndc < 1.0f && -1.0f < x_ndc && x_ndc < 1.0f)

Случай 1) соответствует использованию уравнения 14.10 для их интерполяции. Случай 2) соответствует использованию уравнения 14.9 для интерполяции.

Результаты documented in gifs on imgur. 1) Странные вещи случаются, когда второй куб находится за камерой или когда я иду в куб. 2) Странные артефакты не видны, но по мере приближения камеры к вершинам они начинают исчезать. И так как это вершины perspective correct interpolation of attributes (ближе к камере?) Имеют больший вес, поэтому, как только вершина обрезается, эта информация интерполируется с сильным весом на треугольные пиксели.

Все это ожидается или я сделал что-то не так?

+1

Я не знаю, что вы здесь делаете. Как уже отмечал Никол Болас, отсечение действительно важно, если какой-либо примитив пересекает плоскость 'z_eye = 0'. И интерполяция для таких примитивов станет совершенно бессмысленной (а для некоторой вершины точно в 'z_eye = 0', вы даже закончите с делением на ноль). Проверка в '-1 <= x, y, z <= 1' в NDC не эквивалентна' -w <= x, y, z <= w' в пространстве клипов, так как точки, выполняющие 'w <= x, y, z, <= -w' (за камерой) также выполнит это. Я понятия не имею, что вы подразумеваете под «NDC.w», поскольку в NDC нет w (или это будет 1). – derhass

+1

Подводя итог этому: на мой взгляд, отсечение в пространстве экрана просто не имеет ни малейшего смысла (ведь вы выполняете [растеризацию в однородных координатах] (http://www.cs.unc.edu/~olano/papers/2dh-tri /)), и это будет намного медленнее. Поэтому я не знаю, что вы здесь получаете. – derhass

+0

Спасибо за разъяснение derhass. Тогда я не понял ответ Николь правильно (я думал, он имел в виду, что математика может работать даже в случае отсечения против z_eye = 0). В моем коде я использовал NDC.w как пространство камеры z вершины. По общему признанию, это не имеет смысла после перспективного разделения. – pseudomarvin

ответ

2

Обрезание на ближней плоскости не является абсолютно необходимым, если треугольник не проходит или не проходит 0 в пространстве камеры Z. Как только это произойдет, однородная координатная математика становится странной.

Большинство аппаратных средств беспокоит только треугольники, если они расширяют ширину экрана вне пространства клипа или пересекают камеру-Z нуля. Такой клиппинг называется «обрезкой защитной полосы», и это экономит много производительности, поскольку отсечение не дешево.

Так что да, математика может работать нормально. Главное, что вам нужно сделать, при настройке строк сканирования - выяснить, где каждый из них запускается/заканчивается на экране. Интерполяционная математика одинакова в любом случае.

+0

Я использую функцию edge, чтобы проверить, находится ли пиксель в треугольнике, поэтому в моем случае «настройка строк сканирования» может быть эквивалентно итерации по Min BB треугольных координат в пространстве экрана, зажатых в диапазоне [0, ширина - 1], [0, height - 1], правильно? – pseudomarvin

2

Я не вижу причин, почему это не сработает. Но это будет путь медленнее, чем традиционный клиппинг. Обратите внимание, что у вас могут возникнуть проблемы с треугольниками, расположенными вблизи проекционного центра, так как они будут исчезающе малыми и могут вызвать проблемы при вычислении барицентрических координат.

Разница между уравнениями 14.9 и 14.10 заключается в том, что глубина в основном равна z/w (и заменяется на [0, 1]). Так как перспектива разделения уже произошла, ее нужно оставить во время интерполяции.