タイルベースの滑らかな照明を実装するにはどうすればよいですか?


8

私は2Dタイルゲームに取り組んでおり、ハードエッジのライティングを実装しました。

ここに画像の説明を入力してください

少し滑らかにしてほしい。影などは必要ありません。単純な照明だけです。私はそれを次のように見せたいです:

ここに画像の説明を入力してください

私の現在のシステムは、世界の各タイルの光レベルを使用しており、タイルが配置または削除されると、それらは再計算されます。batch.setColor(...)タイルの陰影に使用しています。この滑らかな照明を実現する良い方法は何ですか?

ライトマップオーバーレイメソッドを使用したくありません。すでに試してみましたが、結果に満足できませんでした。ブロックを通過できる光の量を設定できるようにしたい。たとえば、ダートブロックは光の一部を吸収する必要がありますが、ガラスブロックは光を遮るべきではありません。これは、ライトマップオーバーレイメソッドでは実際には不可能でした。更新:私はこの方法が実際に何であるかを誤解しました。今、私は分かる。私は間違った方法で考えていました。ごめんなさい!


正直なところ、エッジの効いた照明でよりスタイリッシュに見えます。
S.TarıkÇetin16年

私はあまり好きではありません。また、このスタイルで背景タイルと前景タイルを区別するのは少し難しいです。
ProRed 2016

回答:


15

タイルベースのゲームでスムーズなライティングを実現する簡単な方法は、レンダーターゲットに「ライトマップ」を描画し、アルファブレンドしながらシーンの上にこのレンダーターゲットを描画することです。

ライトマップのレンダーターゲットはタイルマップのサイズですが、ピクセル単位です。各ピクセルは、対応するタイルの明るい色を表します。このレンダーテクスチャは次のようになります(左上のテクスチャは白黒です)。

ここに画像の説明を入力してください

このライトマップテクスチャを取得したら、それをゲームの世界の上にオーバーレイとして描画できます(ストレッチ)。あなたはそれを適切にクランプしなければなりません、それでそれがゲームの世界であなたのタイルの上に完全に伸びるようにします。

次に、このテクスチャをlibGDXのゲームワールドにアルファブレンディングします。LibGDX(個人的にはわかりません)でブレンドするには、Gdx.gl.glBlendFunc関数を確認する必要があります。


2
あなたはこのシステムであなたが望む方法で照明を制御することができます。光を遮ることができないと言うとき、あなたが何を参照しているのかわからない また、文字通りタイルを着色している​​だけなので、現在のシステムをどのようにスムーズにするかは完全にはわかりません。
jgallant

4
ちなみに、このシステムはStarboundのやり方です。
Qqwy 2016

2
これは優れたアプローチであり、必要に応じて柔軟に対応できます。私はこれを、シェーダーにアクセスできないタイルベースのゲームで使用しています。
Tyyppi_77 2016

1
更新:これは行く方法のようです、私はこの方法を誤解し、今完全に理解しました!私はこの方法を今実装しようとします、そして私はこれを最良の答えとしてマークし、あなたに賞金を与えます!
ProRed

2
それを行う方法についてさらに質問がある場合は、遠慮なく尋ねてください。私はこれを実装し、@ Tyyppi_77も最近実装しました。私はXNA / MonogameとUnityでそれを行いました。TyyppiはSDLでそれを行いました。
jgallant

4

エンジンにとらわれない方法は、平均的なライトマッピングを使用することです。まず、ブロックがTrueで空がFalseである世界のサイズであるブール値の2D配列として白黒マップを生成する必要があります。

このように(1は黒、0は白): 地図

次に、最初の配列と同じサイズで、浮動小数点数の配列である新しい2D配列を作成する必要があります。次に、配列内の黒(True)ブロックから黒ブロックに移動し、近くのサンプル値を平均します(以下で説明)

この画像は役立ちます: 平均した

この画像はサンプリングを表しています(+はfalseを意味し、|はtrueを意味します)。True値を1として、False値を0として扱います。次に、9つの数値を平均し、それを配列の正しい部分に配置します。注:エッジをサンプリングするときは、外側の値を状況依存として扱うことを確認してください。たとえば、地下の世界外のマップは1で、空は0である必要があります。

次のようになります(他の投稿から取得)。終わり

その後、あなたがしなければならないすべては、配列の各ブロックに

rgba(tint,tint,tint,1)

(tint = 2番目の配列の現在の平均ブロック値で、アルファは関係ありません)。注:これは、疑似関数rgbaが0-255ではなく0-1から浮動小数点数を取ることを前提としています。

rgba(tint*255,tint*255,tint*255,255)

これが少し理にかなっていることを願っています:)コードが必要な場合は、質問してください!


あなたの答えに感謝しますが、問題は私がすでにゲームにハードエッジ照明を持っていることです(ここ)。私はこれをもっと滑らかに見えるように変更する方法を尋ねました(このように
ProRed

1

あなたは光を遮るものについて話しているので、あなたは光がどのように広がるべきかについてのモデルを持っていると仮定します。たとえば、その上にブロックがないものはすべて完全に照らされ、光はすべての隣接するセルに広がりますが、一定の明るさを失います。

ソフトウェア側でこれらのルールをかなり簡単に実装できるはずです。少なくともスムージングの部分は、生成したライトマップにシェーダーを投げるだけです。

他の人がライトマップのオーバーレイに関して提案した方法は、とにかくやるべきことです。ただし、このライトマップの生成方法を変更できます。最初はブロック情報のみで埋めることができますが、その後、拡大してシェーダーなどで滑らかにすることができます。ライトマップアプローチのもう1つの利点は、動的なライトをライトマップに描画するだけで、爆発や何を持っているかを強調でき、他の世界と自然に調和することです。

ライトマップに加算ブレンドを行ってから、ライトマップをゲームの世界と乗法的にブレンドします。

私がやったこの同じ原則を使用する前にしながら、Aを。このシステムは、異なるタイプの地形に対して異なる光の落下をサポートしていませんが、少なくともライトマップのオーバーレイの有用性を示しています。


わかりましたので、2番目のレンダーターゲットに対応するタイルのサイズと正確に一致する長方形の形でライトレベルをレンダーしますか?そして、私はそれをどのように平滑化しますか?
ProRed

レンダリングするときは線形補間されるので、GPUにダウンサンプリングすることでGPUに処理させることができます。それでも十分でない場合は、シェーダーでぼかしを実行できます。隣接するタイルに応じて異なる方法で描画する場合は、タイルの解像度よりも細かいレンダリングを検討することもできます。基本的に難しいのは、どの領域をどれだけ明るくするかについて、特定のルールを作成することです。これらのルールを書き留めておくと、通常はかなり簡単な方法で見つけることができます。
Nils Ole Timm

1

トーチは非常に簡単です。カスタムピクセルシェーダーを使用して、各フラグメントとトーチの間の距離を計算します。次に、トーチからの光を遮る最初の密なタイルの場所を計算できます。次に、光が遮られない距離を計算し、それを<1で乗算してトーチが太陽を照らさないようにし、合計距離からそれを差し引いて、残りの距離(光が遮られた場所)について繰り返します少なくとも1つのタイル)乗算値がはるかに小さい...私はこの計算を行う方法を知っており、openglで実装するのはそれほど複雑ではありません。

編集:特定の中心点を持つ単純な光源の場合、私の方法は非常に簡単です。しかし、私のものは太陽光では機能しませんが、アルファマップは太陽光では非常にうまく機能しますが、トーチは移動する可能性があるため、トーチには適していません。人生経験。私の意見で最良の解決策はミックスです:実際にゲーム内のオブジェクトである特定のライトの距離計算、上記のテクニックを使用して手続き的に生成したアルファマップの上に投げる別のシェーダー:すべてのテクスチャハードシェーディングからのタイルアルファをたくさんの正方形として、滑らかにするためのテクニックをいじります。


0

レンダリングでは頂点カラーを使用していますか(または変更できますか)?

各ブロックが4頂点の正方形であるとすると、たとえば次のような2つのオプションが得られます。

現在のライティングアルゴリズムでブロックごとのライト値が得られる場合は、それを変更して頂点ごとの値を与えることができます。または、各頂点で、現在のブロックとその3つの隣接ブロックの明るい色を平均化することもできます。どちらのソリューションも安価です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.