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

При рендеринге неба с фиксированной текстурой в 3D-играх люди часто сначала создают 6 текстур в кубической карте, а затем рендерят куб вокруг камеры. В GLSL вы можете получить доступ к пикселям в текстурах с помощью нормали вместо координаты текстуры, и вы можете легко получить эту нормаль, нормализовав положение фрагмента относительно камеры. Однако этот процесс можно выполнить с любой формой, окружающей камеру, потому что при нормализации каждой позиции всегда получается сфера. Теперь мне интересно: почему всегда куб, а не тетраэдр? Рендеринг куба требует 12 треугольников, тетраэдра только 4. И, как я уже сказал, любая фигура, окружающая камеру, работает. Получается, что тетраэдры требуют меньше видеопамяти и быстрее рендерятся без каких-либо недостатков? Почему бы не использовать их?


person Pikaju    schedule 03.05.2015    source источник
comment
Скайбоксы просты в реализации и легко определяют координаты текстур. Вот почему это более распространено.   -  person Berke Cagkan Toptas    schedule 03.05.2015
comment
Ну, вам не нужны текстурные координаты. Я предполагаю, что выяснить положение вершины немного сложно.   -  person Pikaju    schedule 03.05.2015


Ответы (2)


Вам вообще не нужна геометрия окружения. Все, что вам нужно сделать, это нарисовать полноэкранный четырехугольник и просто вычислить для него правильные координаты текстуры. Теперь с современным GL нам даже не нужно предоставлять данные вершин для этого, мы можем использовать рендеринг без атрибутов:

Вершинный шейдер:

#version 330 core
out vec3 dir;
uniform mat4 invPV;
void main()
{
        vec2 pos  = vec2( (gl_VertexID & 2)>>1, 1 - (gl_VertexID & 1)) * 2.0 - 1.0;
        vec4 front= invPV * vec4(pos, -1.0, 1.0);
        vec4 back = invPV * vec4(pos,  1.0, 1.0);

        dir=back.xyz / back.w - front.xyz / front.w;
        gl_Position = vec4(pos,1.0,1.0);
}

где invPV равно inverse(Projection*View), поэтому будет учитываться ориентация вашей камеры, а также проекция. В принципе, это можно еще больше упростить, в зависимости от того, сколько ограничений вы можете наложить на матрицу проекции.

Фрагментный шейдер:

#version 330 core
in vec3 dir;
out color;
uniform samplerCube uTexEnv;
void main()
{
        color=texture(uTexEnv, dir);
}

Чтобы использовать это, вам просто нужно связать пустой VAO и вашу текстуру, загрузить свою матрицу invPV и вызвать glDrawArrays(GL_TRIANGLE_STRIP, 0, 4).

Этот подход, конечно, можно использовать для наложения сферических текстур вместо кубических карт.

person derhass    schedule 04.05.2015
comment
Хорошая работа по преобразованию из проекционного пространства для использования с квадратом экрана, дополнительные баллы за отсутствие атрибутов. - person Joshua Hyatt; 13.08.2020

  1. это вопрос глубины и формы просмотра

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

    пример кубического искажениявведите здесь описание изображения

    это связано с изменением расстояния между скайбоксом и камерой. Если вы сравните это с напрямую визуализированной звездой:

    рендеринг неба (без скайбокса)

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

    Таким образом, чем дальше форма от сферы, тем больше искажений вы получите.

    использование 4-сторонней пирамиды еще хуже, чем куба, потому что углы между сторонами хуже, создавая еще большие артефакты. Другая проблема заключается в том, что вам нужен больший размер пирамиды, чтобы покрыть то же пространство. Если вы используете Depth Buffer для какой-либо цели во время рендеринга skybox, вы можете значительно повлиять на точность, увеличив плоскость Z_far.

  2. Накладные расходы

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

  3. Сферические скайбоксы

    им нужен другой тип текстуры. Полусферическая текстура выглядит так:

    полусферическая текстура

person Spektre    schedule 04.05.2015
comment
Ты уверен насчет этого? Если бы я использовал 6 стандартных текстур и сопоставил их с кубом с нормальными текстурными координатами, то да, это исказилось бы. Но так как я нормализую положение вершин во фрагментном шейдере, то у меня получается сфера, а как вы уже сказали, сфера идеально подходит для скайбокса. И еще, интерполяция граней действительно не должна иметь значения, так как размер модели совершенно не имеет значения (если буфер глубины отключен)... - person Pikaju; 04.05.2015
comment
@Pikaju Я согласен, но чтобы это работало, вам нужна сферическая текстура вместо кубической, иначе у вас будет идеальный сферический скайбокс с искаженной текстурой, который имеет такие же результаты, как кубический скайбокс. - person Spektre; 04.05.2015
comment
@Pikaju добавил изображение полусферической текстуры в конец ответа - person Spektre; 04.05.2015
comment
@Pikaju: нет, вам не нужны сферические текстуры, кубические карты подойдут для этого. У вас всегда есть неоптимальная параметризация при сопоставлении сферы с 2D-текстурой. Это не означает, что вы получаете искажения изображения, это просто означает, что эффективное разрешение будет варьироваться в зависимости от того, где находится ваш образец. Для кубических карт наихудшим случаем является выборка из углов. - person derhass; 04.05.2015