OpenGL ES отбрасывает тени для 2D спрайтов

У меня есть сцена OpenGL, созданная с кучей спрайтов, и я хотел бы автоматически добавлять тени для всех. Вот картина, показывающая, что я имею в виду:

Введите описание изображения здесь

Сцена использует орфографическую проекцию, спрайты – текстурированные квадрациклы, и я использую буфер глубины, чтобы рисовать их спереди назад. Я работаю с OpenGL ES 2.0, но мысли из iOS или не-ES-миров будут оценены. Я бросил в голове несколько идей о том, как я могу это сделать, и я хотел бы узнать, что наиболее перспективно.

  1. Нарисуйте каждый спрайт дважды, первый обычно, второй с каким-то шейдером тени, немного глубже в сцене. Не уверен, что это возможно?
  2. Нарисуйте спрайт, затем снова нарисуйте его, затемненный и с некоторой альфа, несколько раз с некоторым случайным дрожанием, применяемым к вершинам. Это может показаться глупым и совсем не похожим на тень.
  3. Нарисуйте базовую сцену без фона текстуры, затем размывайте и затемните ее, чтобы создать одну большую тень. Затем нарисуйте базовую сцену поверх текстуры тени, затем, наконец, над фоном. Тем не менее это потеряло бы тени между спрайтами.
  4. SSAO в ходе последующей обработки. Могут быть самыми динамичными и автоматическими, но могут выглядеть нечеткими / зернистыми и очень медленными.
  5. Во время создания создайте текстуру тени для каждого спрайта. Для рендеринга нарисуйте sprite, а затем его теневое texuture немного глубже в сцене. Я думаю, что я бы хотел избежать этого из-за времени загрузки и дополнительных требований к памяти, но это может быть самым быстрым и лучшим способом?

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

Так ли это лучше, чем другие? Есть ли другие варианты, о которых я не думаю? Благодаря!

Solutions Collecting From Web of "OpenGL ES отбрасывает тени для 2D спрайтов"

Это все хорошо продуманные варианты, вот мои мысли по каждому

  1. Конечно, возможно использовать шейдер, но это может быть не самый эффективный вариант, так как размытие должно выполняться внутри шейдера и может включать в себя несколько текстурных поисков.
  2. Рисование текстуры несколько раз будет работать и будет выглядеть как тень, потому что каждое «дрожащее» изображение будет иметь слегка измененные альфа-значения. Но опять же, смешение и множественные визуализации каждого спрайта будут складываться и могут повлиять на производительность.
  3. Мне нравится и рекомендую этот параметр, потому что вы можете установить шейдер, который помещает черные пиксели вместо цветных пикселей (учитывая альфу) в цель рендеринга, меньшую, чем экран (1 / 4th?), А затем использовать это как теневую текстуру. Поскольку текстура теперь растягивается, вы также получите «размытие». Шейдер пикселя, который выполняет «чернение», будет очень простым и не слишком сильно влияет на производительность.
  4. Если вам действительно не нужны высококачественные тени (и предыдущего метода не хватает), я бы не рекомендовал этого.
  5. Это, конечно, самый гибкий вариант и имеет сложность рендеринга x2. К сожалению, он будет потреблять больше памяти, чем все другие варианты выше.

Надеюсь это поможет!