box2dlights がアンビエント ライティングのテクスチャとスプライトを無視するようにするにはどうすればよいですか? たとえば、環境照明を暗く設定したステージがあります。ライトの真下にあるプラットフォームをライトで明るくしたいのですが、ライトの背後にある背景画像は暗いままで点灯しないようにする必要があります。現在、ライトはレンダリングされた最上位レイヤーであり、ライトの下にあるすべてが照らされています。
1433 次
1 に答える
3
これを達成する正しい方法は次のとおりです。
- 物理とカメラを更新します。
- ライト マップをレンダリングして、後で からテクスチャを取得できるようにし
RayHandler
ますFrameBuffer
。 - トップ レイヤーを透明な
FrameBuffer
オブジェクトに希望の順序でレンダリングしますが、その中にライト マップをレンダリングしないでください。ここでは、HUD や、照明の影響を受けたくない最上位レイヤーをレンダリングしないでください。 - へのレンダリングを終了
FBO
し、画面へのレンダリングを開始します。 - ライトの影響を受けない背景をレンダリングします。
Texture Units
ライト マップとトップ レイヤーの 0 と 1 にバインドしますFBO
Texture
。- ライト マップと をブレンド
Shader
するために使用する を開始しますFBO
Texture
。混合は非常に単純です ( で発生しますFragment Shader
):glFragColor = tex0.rgb * tex1.rgb
、そのままにしておきtex1.a
ます (tex0
= ライト マップ テクスチャ、tex1
= fbo テクスチャ)。のRayHandler
アンビエント ライトはこのレンダリング方法では失われるため、アンビエント ライトの色をシェーダに渡してライト マップ チャネルに追加できます。 - テクスチャ ユニットをシェーダにバインドし、レンダリングを実行します。このレンダリングは、アルファ ブレンディングを有効にして行う必要があります (SRC_ALPHA、ONE_MINUS_SRC_ALPHA)。
- デフォルトを再度バインドして、
Texture Unit
残りのレンダリングが適切に行われるようにします (TEXTURE_0
): 残りの最上位レイヤーと、存在する場合は HUD をレンダリングします。
いくつかのコード例:
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
tweenManager.update(delta);
worldUpdate(delta);
/* We have three cameras (foreground + double parallax background) */
moveForegroundCamera(player.getPosition().x, player.getPosition().y);
moveBackground0Camera(player.getPosition().x, player.getPosition().y);
moveBackground1Camera(player.getPosition().x, player.getPosition().y);
cameraMatrixCopy.set(foregroundCamera.combined);
rayHandler.setCombinedMatrix(cameraMatrixCopy.scale(Globals.BOX_TO_WORLD, Globals.BOX_TO_WORLD, 1.0f), foregroundCamera.position.x,
foregroundCamera.position.y, foregroundCamera.viewportWidth * camera.zoom * Globals.BOX_TO_WORLD,
foregroundCamera.viewportHeight * foregroundCamera.zoom * Globals.BOX_TO_WORLD);
rayHandler.update();
rayHandler.render();
lightMap = rayHandler.getLightMapTexture();
fbo.begin();
{
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
/* Draw the second background (affected by lights), the player, the enemies and all the objects */
batch.enableBlending();
batch.setProjectionMatrix(background1Camera.combined);
batch.begin();
background1.draw(batch);
batch.end();
batch.setProjectionMatrix(foregroundCamera.combined);
batch.begin();
// Draw stuff...
batch.end();
}
fbo.end();
/* Now let's pile things up: draw the bottom-most layer */
batch.setProjectionMatrix(background0Camera.combined);
batch.disableBlending();
batch.begin();
background0.draw(batch);
batch.end();
/* Blend the frame buffer's texture with the light map in a fancy way */
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
fboRegion.getTexture().bind(); // fboRegion = new TextureRegion(fbo.getColorBufferTexture());
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);
lightMap.bind();
Gdx.gl20.glEnable(Gdx.gl20.GL_BLEND);
Gdx.gl20.glBlendFunc(Gdx.gl20.GL_SRC_ALPHA, Gdx.gl20.GL_ONE_MINUS_SRC_ALPHA);
lightShader.begin();
lightShader.setUniformf("ambient_color", level.getAmbientLightColor());
lightShader.setUniformi("u_texture0", 0);
lightShader.setUniformi("u_texture1", 1);
fullScreenQuad.render(lightShader, GL20.GL_TRIANGLE_FAN, 0, 4);
lightShader.end();
Gdx.gl20.glDisable(Gdx.gl20.GL_BLEND);
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0); // Bind again the default texture unit
/* Draw any top-most layers you might have */
hud.draw();
}
于 2015-06-06T11:02:07.937 に答える