Почему OpenGL имеет плоскость отсечения, и какие идиомы используются для борьбы с этим?

Я изучаю OpenGL, и одна тема, которая продолжает меня беспокоить, - это плоскость отсечения. Хотя я могу понять рассуждения за плоскостью ближнего отсечения и боковыми плоскостями отсечения (которые никогда не имеют реального эффекта, потому что объекты вне их никогда не будут визуализированы), плоскость отсечения кажется только раздражающей.

Поскольку те, кто стоит за OpenGL, очевидно, подумали об этом, я знаю, что мне что-то недостает. Почему OpenGL имеет плоскость отсечения? Что еще более важно, потому что вы не можете отключить его, какие рекомендуемые идиомы и практики использовать при рисовании вещей на огромных расстояниях (для объектов, таких как звезды, тысячи единиц в космической игре, skybox и т.д.)? Ожидаете ли вы просто сделать плоскость отсечения очень далеко, или есть более элегантное решение? Как это делается в производственном программном обеспечении?

Ответ 1

Единственная причина - точность глубины. Поскольку в буфере глубины имеется только ограниченное количество бит, вы также можете просто представить с ним конечную глубину.

Однако вы можете установить дальнюю плоскость бесконечно далеко: см. this. Это просто не очень хорошо работает с буфером глубины - вы увидите много артефактов, если у вас будет окклюзия далеко.

Так как это вращается вокруг буфера глубины, у вас не будет проблемы с дальнейшими вещами, если вы его не используете. Например, общий метод заключается в том, чтобы визуализировать сцену в "слябах", что каждый из них использует внутренний буфер глубины (для всего материала в одной плите), но в какой-то форме алгоритма живописца снаружи (для плит, поэтому вы рисуете самый дальний первая)

Ответ 2

Почему OpenGL имеет плоскость отсечения?

Потому что компьютеры конечны.

Как правило, есть два способа попытаться справиться с этим. Один из способов - построить проекцию, взяв предел, поскольку z-далеко приближается к бесконечности. Это будет сходиться по конечным значениям, но оно может играть хаос с вашей точностью глубины для удаленных объектов.

Альтернативный вариант (если вы хотите, чтобы объекты за определенным расстоянием не выполнялись должным образом, чтобы проверить глубину), необходимо включить глубину зажима с помощью glEnable(GL_DEPTH_CLAMP). Это предотвратит отсечение против ближнего и дальнего плавания; это просто, что любые фрагменты, которые имели бы нормализованные координаты z вне диапазона [-1, 1], будут зажаты в этом диапазоне. Как указывалось ранее, он закручивает тесты глубины между обломочными фрагментами, но обычно эти объекты находятся далеко.

Ответ 3

Это просто "факт", что проверка глубины OpenGL была выполнена в координатах оконного пространства (нормализованные координаты устройства в [-1,1] ^ 3. С дополнительным масштабированием glViewport и glDepthRange).

Итак, с моей точки зрения, это одна из проектных точек зрения библиотеки OpenGL.


Один из способов устранить эту функциональность OpenGL extension/OpenGL core https://www.opengl.org/registry/specs/ARB/depth_clamp.txt, если она доступна в вашей версии OpenGL.


Я хочу описать, что в перспективной проекции ничего не говорится о "плоской плоскости отсечения".

3.1 Для перспективной проекции вам нужно настроить точку \vec {c} как центр проекции и плоскость, на которой будет выполняться проецирование. Позвольте называть это плоскость изображения T: (\ vec {r} -\vec {r_0},\vec {n})

3.2. Предположим, что проекционная плоская T-разбитая точка \vec {r} и \vec {c} центральна проекции. В другом случае \vec {r} и \vec {c} находятся в одном пространстве hafe и точка \vec {r} должна быть отброшена.

3.4. Идея проекции - найти пересечение \vec {i} с плоскостью T \ VEC {I} = (1-т)\VEC {C} + T\VEC {г}

3.5 Поскольку это (\ vec {i} -\vec {r_0},\vec {n}) = 0

= >

((1-t)\vec {c} + t\vec {r} -\vec {r_0},\vec {n}) = 0

= >

(\ vec {c} + t (\ vec {r} -\vec {c}) -\vec {r_0},\vec {n}) = 0

3,6. Из "3.5" полученных t можно подставить в "3.4", и вы получите проекцию в плоскость T.

3,7. После проецирования вы будете лежать в плоскости. Но если предположить, что плоскость изображения параллельна плоскости OXY, то я могу предложить использовать оригинальную "глубину" для точки после проецирования.

Таким образом, с точки зрения геометрии можно вообще не использовать дальнюю плоскость. Также не использовать явно [-1,1] ^ 3 модель.

p.s. Я не знаю, как правильно набирать формулы латекса, s.t. они будут отображаться.