Ответ 1
Хорошо, я думаю, что после долгих исследований я понимаю ошибку в своих мыслях.
Во-первых, есть способ сделать Max Alpha openGL blending, и это использует glBlendEquations. Вам нужно будет изменить метод draw для этого (и создать новый атрибут для функции textureNode для переключения между этими методами) и использовать любой из них:
glBlendEquationOES( GL_MAX_EXT );
glBlendEquationSeparateOES( GL_FUNC_ADD_OES, GL_MAX_EXT );
Первый использует max() для RGBA, а второй использует стандартное дополнение для RGB и max() для альфа.
Теперь проблема заключается в том, что каждый спрайт и его дети в z-порядке обращаются к экрану . Это означает, что после создания первой тени она является частью основного экранного буфера. Другими словами, его непрозрачность изменяется и с max() смешиванием и стандартным непрозрачным фоном, теперь она нарисована на фоне, поэтому, когда вы рисуете следующую тень, она будет делать max (As, 1), которая равна 1, потому что фон непрозрачен. Поэтому я не достигаю того, что хочу. Он "работал", если бы мой фон был прозрачным, но тогда я не мог применить какой-либо фон "позади", который мы можем добавить только в буфер.
Сначала я мог бы нарисовать тени, используя комбинацию max(), а затем выполнить {ONE_MINUS_DST_ALPHA, DST_ALPHA} glBlend. Это обходное решение, но у меня есть другие проблемы, которые затрудняют это.
Теперь, наконец, реальное решение заключается в использовании RenderTexture для визуализации теней в отдельный буфер, прежде чем применять их к фону. Это может иметь последствия для производительности, поэтому мы увидим, где это происходит.
Update:
ОК, теперь у меня есть рабочее решение.
Как ни странно, мне все-таки не понадобилось это решение, потому что в моем конкретном случае полоса не была достаточно заметной, чтобы оправдать усилия, однако это решение, которое я придумал, казалось, делал то, что я хотел:/p >
-
Сначала нарисуйте 0% черный альфа файл на весь экран. (Я не знаю, нужно ли это. Я не знаю, что такое альфа-версия по умолчанию на экране).
-
Нарисуйте тени на экране с помощью
glEquationSeperateOES( GL_ADD, GL_MAX_ENT)
иglBlend( GL_ONE, GL_ONE )
. Это будет смешивать все тени вместе, как описано, принимая max() альфы.-
Поскольку вы составляете композицию на черный, это эквивалентно использованию
glBlendEquationOES( GL_MAX_ENT )
. (X + 0 == max (X, 0)) -
glBlend( GL_ZERO, GL_ONE )
устраняет необходимость в шаге 1 или, по крайней мере, требование того, чтобы этот слой был 0% черного.GL_ZERO
по существу заставляет его быть 0% черного.
-
-
Нарисуйте пол, который будет поверх теней, но используйте
glBlend( ONE_MINUS_DST_ALPHA, DST_ALPHA )
. Это приводит к точно таким же результатам, как если бы вы добавили тени к полу с помощьюglBlend( SRC_ALPHA, ONE_MINUS_SRC_ALPHA )
, однако, если бы вы сделали это таким образом, вы не смогли бы смешать тени вместе (прочитайте, почему в верхней части ответа). -
Вы закончили! Самое приятное в этом методе заключается в том, что теневые спрайты можно анимировать, как обычно, без необходимости называть "посещение" на отдельной рендеринговой текстуре.
Остальное:
Я также модифицировал CocosNode, чтобы я мог добавить тень к слою, который ссылается на другой CocosNode. Таким образом, тень отображается как ребенок пола (или 0% черного фонового спрайта для смешивания теней), но связана с другим CocosNode. Когда спрайт перемещается, если он имеет тень, он также обновляет положение теней. Это позволяет мне иметь все тени под всеми объектами на экране, а тени автоматически следовать за объектом.
Извините за длинный ответ. Возможно, мое решение является kludgy, но, похоже, он отлично работает.