OpenGL - разные текстуры на разных поверхностях одного и того же объекта

Я пытаюсь нарисовать машину для игры, которую я делаю, используя OpenGL. Объект car хранится в файле.obj с сопровождающим файлом.mtl.

Машина имеет более 500 вершин, более 100 граней и требует более 50 различных текстур, примененных к ним, используя мой собственный вершинный и фрагментный шейдер. Я пошел об этом, используя буферные объекты, которые отправляют всю информацию о моем объекте сразу. Моя проблема заключается в попытке применить разные текстуры к разным поверхностям одного и того же объекта.

Я нашел ответы на эту проблему: связать текстуру с определенным номером текстуры (т. Е. GL_TEXTURE0, GL_TEXTURE1 и т. Д.) И передать Sampler2D фрагментному шейдеру, ссылающемуся на него. Тем не менее, я могу хранить более 50 текстур таким образом? Насколько я могу сказать, это идет к GL_TEXTURE32.

Кроме того, как бы я сказал шейдеру применить текстуру только к определенному лицу автомобильного объекта?

3 ответа

Решение

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

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

Правильный способ справиться с этим - сделать одно из следующего:

  1. Вернитесь к моделисту и попросите их уменьшить количество текстур модели.
  2. При помощи инструмента создайте атлас текстуры (т.е. поместите все изображения в одну текстуру), соответствующим образом изменив координаты текстуры модели. В зависимости от оборудования, которое вы планируете поддерживать, это может быть большая 2D-текстура или 2D-массив текстур. Последнее потребует 3-го значения для координаты текстуры: индекс изображения в массиве.
  3. Сортировка треугольников по текстуре. Для каждой текстуры визуализируйте все треугольники, которые используют эту текстуру.

№ 3 - единственное решение, которое не требует изменения данных. Но будьте осторожны: если вы визуализируете этот автомобиль часто (скажем, тысячи раз за кадр), накладные расходы на изменение состояния могут стать проблемой производительности. Некоторая комбинация № 1 и № 2 является обычно предпочтительным методом.

Кстати, если ваша модель имеет только несколько сотен граней, но 50 текстур, то, скорее всего, что-то пошло не так в процессе моделирования.

Невозможно использовать произвольное количество текстур просто так, не так просто.

Есть в основном 3 решения:

  • Используйте меньше текстур
    • Упакуйте несколько отдельных текстур в атлас. Это требует от вас корректировки текстурных координат и осторожности при создании mipmap (хотя достойный инструмент сделает это автоматически). Возможно, вам придется позаботиться о том, чтобы оставить достаточную границу и для анизотропной фильтрации.
    • Упакуйте несколько отдельных текстур в один массив текстур. Нет проблем с mipmaps и aniso, но требуется аппаратная поддержка (карты GL 3.1)
  • Разделите свою модель
    • Больше вызовов отрисовки и еще больше изменений состояния и остановок конвейера на автомобиль (плохо для производительности)
    • Решение: Нарисуйте, например, все кузова автомобиля в одной партии, все шины в одной партии и все фары в другой, чтобы уменьшить изменения состояния
  • Используйте детализацию текстур и меньше текстур "в целом с низкой детализацией"
    • похоже на то, как вы делаете текстурирование на местности
    • объединить в пиксельном шейдере, чтобы придать каждой машине индивидуальный вид

Переключение 50 текстур для одного объекта быстро превратится в кошмар с низкой производительностью. Используйте текстурный атлас.

Мультитекстурирование предназначено для предоставления нескольких текстурных слоев, таких как цветной слой, рельефный слой, блеск и т. Д. Но они не должны использоваться для замены атласа.

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

Другие вопросы по тегам