Нарисуйте текстурированный объект (сферу) с очень высоким разрешением в OpenGL ES

Я рисую планеты в OpenGL ES и сталкиваюсь с некоторыми интересными проблемами производительности. Общий вопрос: как лучше всего отображать "чрезвычайно детализированные" текстуры на сфере?

(сфера гарантирована, меня интересуют сферические оптимизации)

Базовый регистр:

  • Окно ок. 2048 x 1536 (например, iPad3).
  • Карта текстур для земного шара - 24 000 x 12 000 пикселей (площадь, равная половине размера США, соответствует ширине экрана)
  • Глобус отображается во всем, от увеличенного изображения (экран заполнения США), чтобы увеличить масштаб (весь видимый глобус)
  • Мне нужно МИНИМАЛЬНО 3 слоя текстуры (1 для поверхности планеты, 1 для различий день/ночь, 1 для пользовательского интерфейса (hilighting different regions).
  • Некоторые из слоев анимированы (т.е. им приходится быстро загружать и удалять текстуру во время выполнения)

Ограничения:

  • верхние планшеты ограничены текстурами 4096x4096.
  • верхние планшеты ограничены 8 одновременными текстурными единицами

Проблемы:

  • В целом, наивно 500 миллионов пикселей данных текстуры
  • Разделение на более мелкие текстуры не работает, потому что устройства имеют только 8 единиц; с единственным слоем текстуры, я мог бы разбиться на 8 текстурных единиц, а все текстуры будут меньше 4096x4096, но это позволяет только один слой
  • Рендеринг слоев в виде отдельной геометрии работает плохо, потому что их нужно смешивать с использованием фрагментарных шейдеров

... на данный момент, единственная идея, которая у меня есть, кажется жизнеспособной:

  • разделить сферу на NxM "кусочки сферы" и сделать каждый из них отдельной геометрией.
  • использовать mipmaps для рендеринга текстур с низким разрешением при масштабировании
  • ... полагаться на простое отбраковывание, чтобы вырезать большую часть из них при увеличении, и mipmapping для использования небольших (er) текстур, когда они не могут быть отобраны.

... но кажется, что должны быть более простые способы/лучшие варианты?

Ответ 1

Похоже, что нет возможности подгонять такие огромные текстуры в память мобильного GPU, даже в iPad 3.

Итак, вам нужно передать данные текстуры. То, что вам нужно, называется clipmap (популяризированное программным обеспечением id с расширенной технологией мегатекстуры).

Пожалуйста, прочитайте об этом здесь, есть ссылки на документы, описывающие технику: http://en.wikipedia.org/wiki/Clipmap

Ответ 2

Это нелегко сделать в ES, поскольку нет расширения виртуальной текстуры (пока). Вам в основном необходимо реализовать виртуальное текстурирование (некоторые ES-устройства реализуют ARB_texture_array) и поток с минимальным разрешением (зависит от вашего зрения) для вашей сферы. Таким образом, все это можно сделать в шейдере фрагмента, не требуется разделение геометрии. См. эту презентацию (и документ) для подробностей о том, как это можно реализовать.

Если вы выполняете математику, просто невозможно передать 1 ГБ (24 000 x 12 000 пикселей x 4 B) в реальном времени. И это было бы расточительно, так как пользователь никогда не сможет увидеть все это одновременно.