web-dev-qa-db-ja.com

LibGDXでブレンディングを行う方法

基本的にLibGDXのブレンディングモードを試してみたいのですが、その方法がわかりません。この画像をインターネットで見つけました。 LibGDXでも同じことをしたいです。誰かが私にその方法を教えてもらえますか?.

enter image description here

私はScene2Dを使って遊んでいます。これが私の機能しないスニペットです。

private class MyGroup extends Group {

    Image red, blue;

    public MyGroup() {
        Texture texture = new Texture(Gdx.files.internal("images/red.png"));
        texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        red = new Image(texture);

        texture = new Texture(Gdx.files.internal("images/blue.png"));
        texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        blue = new Image(texture);

        red.setX(-25);
        blue.setX(25);
    }
    @Override
    public void draw(Batch batch, float parentAlpha) {
        batch.end();
        batch.begin();
        batch.enableBlending();

        red.draw(batch, parentAlpha);

        Gdx.gl.glEnable(Gdx.gl20.GL_BLEND);
        Gdx.gl.glBlendFuncSeparate(
                Gdx.gl20.GL_DST_COLOR, 
                Gdx.gl20.GL_SRC_COLOR,
                Gdx.gl20.GL_ONE,
                Gdx.gl20.GL_ONE);

        blue.draw(batch, parentAlpha);
    }
}
17
Ezekiel Baniaga

これは新しい質問ではないことはわかっていますが、OpenGLでのレンダリングについてあまり知らなくても、この質問/回答に答える他の人に情報を共有したいと思いました(これらの用語を知っていると非常に役立ちますミックスアンドマッチングを推測しているだけではありませんこのサイト は私がこれのほとんどを自分で学んだ方法であることに注意してください。したがって、より完全な情報がそこにあります。

Destination Color:バッファ内の色。変更または新しい値で上書きされない限り、(最終的には)描画されます。

ソースカラー:追加のレンダリングコマンドから入力されるカラー。宛先カラーと相互作用する場合としない場合があります(設定によって異なります)。

デフォルトのブレンド方程式:最終色=(SourceColor * SourceBlendingFactor)+(DestinationColor * DestinationBlendingFactor) このデフォルトの式は変更できますが、詳細については上部のソースリンクを読むことをお勧めします

2つのBlendingFactorは、私たちがいじることができるものです。それらを次のように設定できます。

GL_ZERO:RGB(0,0,0)A(0)
GL_ONE:RGB(1,1,1)A(1)
GL_SOURCE_COLOR:RGB(sourceR、sourceG、sourceB)A(sourceA)
GL_ONE_MINUS_SRC_COLOR:RGB(1-sourceR、1-sourceG、1-sourceB)A(1-sourceA)
GL_DST_COLOR:RGB(destinationR、destinationG、destinationB)A(destinationA)
GL_ONE_MINUS_DST_COLOR:RGB(1-destinationR、1-destinationG、1-destinationB)A(1-destinationA)
GL_SRC_ALPHA:RGB(sourceA、sourceA、sourceA)A(sourceA)
GL_ONE_MINUS_SRC_ALPHA:RGB(1-sourceA、1-sourceA、1-sourceA)A(1-sourceA)
GL_DST_ALPHA:RGB(destinationA、destinationA、destinationA)A(destinationA)
GL_ONE_MINUS_DST_ALPHA:RGB(1-destinationA、1-destinationA、1-destinationA)A(1-destinationA)
GL_SRC_ALPHA_SATURATE:RGB(min(sourceA、1-destinationA)、min(sourceA、1-destinationA)、min(sourceA、1 -宛先A))A(1)

以下も、事前定義された一定の色を使用しています。デフォルトでは黒です
GL_CONSTANT_COLOR:RGB(constantR、constantG、constantB)A(constantA)
GL_ONE_MINUS_CONSTANT_COLOR:RGB(1-constantR、1-constantG、1-constantB)A(1-constantA)
GL_CONSTANT_ALPHA:RGB(constantA、constantA、constantA)A(constantA)
GL_ONE_MINUS_CONSTANT_ALPHA:RGB(1-constantA、1-constantA、1-constantA)A(1-constantA)

したがって、これらはすべて事前定義されたfloat値であり、ソースまたは宛先のいずれかと乗算されてから、もう一方に追加されます。

画像から観察するのが最も簡単なのはGL_ZEROとGL_ONEです。最終的には、どちらの画像でも1つになります。


GL_DST_COLORでGL_ZEROを理解する

GL_ZEROが宛先にある場合、現在バッファにある色情報を無視します(すべてにゼロを掛けるため)。ただし、ソースイメージにもGL_DST_COLORを使用すると、ソースと宛先の値であるr、g、bを乗算することになります。

サンプル画像の性質上、これは画像では見栄えがします。 1つは単色の画像として機能し、もう1つのグレースケール画像は光のビームのように見えて機能し、GL_ZERO設定から色を「明らかに」します。

うまくいけば、これは私たちが上で見ることができる画像を説明するのに役立ち、それらの画像が実際にどのようにブレンドされているかを誰もが理解するのに役立ちます。

16
DoubleDouble

さて、私の質問に部分的に答えるために、これが私が使用したトリックです。何かおかしいことがあったら教えてください。注:これは他の関数では機能しません。GL_DST_COLORとGL_ZEROを組み合わせる場合と同様に、必要なものが出力されません。しかし、他の人はそうするでしょう。だから、それで遊んでください。私はまだここで他の答えを探しています。

コードは次のとおりです。

private class MyGroup extends Group {

    Texture dst, src;

    public MyGroup() {
        dst = new Texture(Gdx.files.internal("images/dst.png"));
        dst.setFilter(TextureFilter.Linear, TextureFilter.Linear);

        src = new Texture(Gdx.files.internal("images/src.png"));
        src.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        // We need to cast to use blending function
        SpriteBatch sb = (SpriteBatch)batch;

        // draw our destination image
        sb.draw(dst, 0, 0);
        sb.end();

        // remember SpriteBatch's current functions
        int srcFunc = sb.getBlendSrcFunc();
        int dstFunc = sb.getBlendDstFunc();

        // Let's enable blending
        sb.enableBlending();
        sb.begin();

        // blend them
        b.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA);
        sb.draw(src, 0, 0);

        // Reset
        sb.end();
        sb.begin();
        sb.setBlendFunction(srcFunc, dstFunc);

    }
}
3
Ezekiel Baniaga