OK、よく調べてみると、自分の考えの誤りに気づいたと思います。
まず、Max Alpha openGLブレンディングを行う方法があり、それはglBlendEquationsを使用しています。これを行うには、drawメソッドを変更し(そして、textureNodeにこれらのメソッドを切り替えるための新しい属性を作成し)、次のいずれかを使用する必要があります。
glBlendEquationOES( GL_MAX_EXT );
glBlendEquationSeparateOES( GL_FUNC_ADD_OES, GL_MAX_EXT );
1つ目はRGBAにmax()を使用し、2つ目はRGBに標準加算を使用し、alphaにmax()を使用します。
ここで問題となるのは、各スプライトとその子がzオーダーで画面に描画されることです。これは、最初のシャドウが描画された後、それがメイン画面バッファの一部であることを意味します。つまり、不透明度が変更され、max()ブレンドと標準の不透明な背景で、背景にペイントされるようになりました。次のシャドウを描画すると、max(As、1)が1になります。背景は不透明です。だから私は私が望むブレンドを達成していません。背景が透明であれば「機能」しますが、その「背後」に背景を適用することはできず、バッファに追加することしかできません。
max()ブレンドを使用して最初にシャドウを描画し、次に{ONE_MINUS_DST_ALPHA、DST_ALPHA}glBlendを実行できます。これは問題のない回避策ですが、これを困難にする他の問題があります。
さて、私がついに気付いた本当の解決策は、RenderTextureを使用して、シャドウを背景に適用する前に別のバッファーにレンダリングすることです。これはパフォーマンスに影響を与える可能性があるため、これがどこに行くのかを見ていきます。
アップデート:
OK、私は今、実用的な解決策を持っています。
奇妙なことに、結局、この解決策は必要ありませんでした。私の特定のケースでは、バンディングが努力を正当化するほど目立たなかったためですが、これは私が思いついた解決策であり、私が望んでいたことを実行しているようです。
まず、画面全体に0%の黒のアルファpngを描画します。(これが必要かどうかはわかりません。画面のデフォルトのアルファが何であるかわかりません)。
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 )
ますが、この方法で追加した場合、影をブレンドすることはできません(回答の上部にある理由をお読みください)。
これで完了です。このメソッドの良いところは、別のrenderTextureで「visit」を呼び出すことなく、シャドウスプライトを通常どおりにアニメーション化できることです。
残り:
また、CocosNodeを変更して、別のCocosNodeにリンクするシャドウをレイヤーに追加できるようにしました。このように、シャドウは床の子としてレンダリングされます(または、シャドウブレンディングの場合は0%の黒の背景スプライト)が、別のCocosNodeにリンクされます。スプライトが移動すると、シャドウがある場合は、シャドウの位置も更新されます。これにより、画面上のすべてのオブジェクトの下にすべての影を配置し、影を自動的にオブジェクトに追従させることができます。
長い答えでごめんなさい。たぶん私の解決策は厄介ですが、それはうまくいくようです。