Хорошо, я думаю, что после долгих исследований я осознал ошибку в своем мышлении.
Во-первых, есть способ сделать смешивание Max Alpha openGL, и это использование glBlendEquations. Для этого вам нужно будет изменить метод рисования (и создать новый атрибут для 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 для рендеринга теней в отдельный буфер перед их применением к фону. Это может повлиять на производительность, так что посмотрим, куда это пойдет.
Обновление:
Хорошо, теперь у меня есть рабочее решение.
Как ни странно, в конце концов мне это решение не понадобилось, потому что в моем конкретном случае полоса не была достаточно заметной, чтобы оправдать усилия, однако это решение, которое я придумал, казалось, делало то, что я хотел:
Сначала нарисуйте 0% черный альфа-канал png на весь экран. (Я не знаю, нужно ли это. Я не знаю, какая альфа экрана по умолчанию).
Нарисуйте тени на экране, используя glEquationSeperateOES( GL_ADD, GL_MAX_ENT)
и glBlend( GL_ONE, GL_ONE )
. Это соединит все тени вместе, как описано, взяв max() альфы.
Поскольку вы компонуете в черный цвет, это эквивалентно использованию glBlendEquationOES( GL_MAX_ENT )
. (Х+0 == макс(Х,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 )
, однако, если бы вы сделали это таким образом, вы не смогли бы смешать тени вместе (читайте почему в начале ответа).
Вы сделали! Преимущество этого метода в том, что спрайты теней можно анимировать как обычно, без необходимости вызывать "visit" для отдельной текстуры рендеринга.
Остальное:
Я также модифицировал CocosNode, чтобы добавить тень к слою, который ссылается на другой CocosNode. Таким образом, тень визуализируется как дочерний элемент пола (или спрайт с черным фоном 0% для смешивания теней), но связана с другим CocosNode. Когда спрайт движется, если у него есть тень, он также обновляет положение тени. Это позволяет мне иметь все тени под всеми объектами на экране, и тени автоматически следуют за объектом.
Извините за длинный ответ. Может быть, мое решение глупо, но, похоже, оно отлично работает.
person
Jeff B
schedule
27.01.2010