Действительно ли возможно достигнуть МАКСА (Как, Реклама) openGL смешивание?

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

Я не могу просто представить их в спрайте png, или тени перекроют смежные спрайты.

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

Эти спрайты анимированы, таким образом, не выполнимо представить их в массе.

В основном я хочу, чтобы тени спрайтов смешались вместе таким образом, что они истратили в непрозрачности набора. Пример:

enter image description here

Я полагаю, что это эквивалентно смешиванию openGL (RS, Gs, бакалавр наук, Max (Как, Ds)), где я действительно не забочусь о R, G, и B, поскольку это всегда будет то же, раскрашивают src и dst.

Однако это не допустимый openGL режим наложения. Существует ли простой способ выполнить это, особенно в cocos2d-iphone?

Я смог бы приблизить это путем создания теневых спрайтов непрозрачными, затем применения их обоих к родительскому спрайту и создания родительской непрозрачности 40% спрайта. Однако путь cocos2d работы, это только устанавливает непрозрачность каждого ребенка к 40%, а не объединенного изображения спрайта, которое приводит к той же дорожке.

17
задан Jeff B 9 December 2015 в 18:13
поделиться

1 ответ

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

Во-первых, есть способ сделать максимальную смесь Alpha OpenGL, и это использует Glblendequalies. Вам придется изменить метод draw для этого (и сделать новый атрибут для текстового элемента для переключения между этими методами) и использовать любой из них:

 glBlendEquationOES( GL_MAX_EXT );
 glBlendEquationSeparateOES( GL_FUNC_ADD_OES, GL_MAX_EXT );

первое использование Max () для RGBA, а второй использует стандарт Дополнение для RGB и MAX () для альфа.

Теперь проблема заключается в том, что каждый спрайт, и это дети, в Z-порядке, обращается к экрану . Это означает, что после того, как первая тень нарисована, она является частью основного буфера экрана. Другими словами, его непрозрачность изменена, а с Max () смешиванием и стандартным непрозрачным фоном, теперь она окрашена на фоновом режиме, поэтому, когда вы нарисуете следующую тень, он будет делать максимум (как, 1), что является 1, потому что Фон непрозрачный. Так что я не добиваюсь смешивания, которую я хочу. Это «работа», если мой фон был прозрачным, но тогда я не мог нанести ни один фон «позади», что мы можем добавить только в буфер.

Я мог сначала нарисовать тени, используя Max () Blend, а затем сделать {one_minus_dst_Alpha, dst_alpha} glblend. Это нормальный обходной путь, но у меня есть другие проблемы, которые делают это сложным.

Теперь реальное решение, я, наконец, понимаю, состоит в том, чтобы использовать Rendexture, чтобы сделать тени отдельным буфером перед применением их на фоновом режиме. Это может иметь последствия для производительности, поэтому посмотрим, где это идет.

Обновление:

Хорошо, сейчас у меня есть рабочий раствор.

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

  1. Сначала нарисуйте 0% черный альфа PNG на весь экран. (Я не знаю, необходимо ли это. Я не знаю, что такое альфа по умолчанию экрана).

  2. Нарисуйте тени на экран, используя GLEQUATIONSEPERATEOOE (GL_ADD, GL_MAX_ENT) и GLBLEND (GL_ONE, GL_ONE) . Это будет смешивать все тени вместе, как описано, принимая максимальный () альфа.

    • Поскольку вы композитеруете черное, это эквивалентно использовать GLBlendequationo (GL_MAX_ENT) . (X + 0 == max (x, 0))

    • GLBLEND (GL_ZERO, GL_ONE) устраняет необходимость шага 1 или, по крайней мере, требование этого слоя на 0% черного цвета. GL_ZERO По сути, по сути заставляет его быть 0% черным.

  3. Нарисуйте пол, который будет через тени тени, но используйте Glblend (one_minus_dst_Alpha, dst_alpha) . Это приводит к тому же тем же результатам, что и если бы вы добавили тени на пол с помощью Glblend (SRC_ALPHA, ONE_MINUS_SRC_ALPHA) , однако, если вы сделали это, вы бы не сможете объединить тени (прочитать Почему в верхней части ответа).

  4. Вы сделали! Приятная вещь об этом методе состоит в том, что теневые спрайты могут быть анимированы как обычно, без необходимости вызывать «посещение» на отдельной Rendexture.

Остальные:

Я также модифицировал Cocosnode, чтобы мне добавить тень на слой, который ссылается на другой Cocosnode. Таким образом, тень оказывается как ребенок пола, (или 0% черный фоновый спрайт для смешивания тени), но связан с другим Cocosnode. Когда спрайт движется, если у него есть тень, она также обновляет позицию теней. Это позволяет мне иметь все тени ниже всех объектов на экране, и чтобы тени автоматически следуют объекту.

Извините за длительный ответ. Возможно, мое решение является Kludgy, но, похоже, отлично работает.

18
ответ дан 30 November 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: