2016-12-18 22 views
1

私はlibGDXに基づいた私のゲームで単純な2D光エンジンを実装しようとしています。アイデアは、シェーダなしでこのライトエンジンを作成することです。私は今のところ影を描こうとは考えていません。 私は、三角形や勾配を有する光マップをレンダリングするために管理しているが、問題は、複数の光源が重なった場合、私はこの写真のように、いくつかの人工物を得たことである:2D光拡散マップartif

enter image description here

黄色光源が暗く産れます他の光源と重なり合うときに境界を定める。

私はライトをレンダリングするために、次のブレンド機能を使用しています:

Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_ONE); 

は、この暗い国境を取り除く方法はありますか?

グラデーションは、黄色から黒色の完全な不透明度になります。 GL_ONEは加法的であると考えられるので、色はより明るくなるはずですか?

アップデート1:シェーダを使用して

ニコSchertlerで説明したように確かに良いですが、私はわからないいくつかのパラメータが残っています。

enter image description here

ここで私は

void main() { 
    float intensity = 0.02; 
    vec2 pos = vPosition; 
    float dist = distance(pos, u_origin)/u_radius; 
    vec4 color = vec4(intensity * (vColor.rgb/((dist * dist) + 0.01)), 1); 
    gl_FragColor = color; 
} 

を思い付いたフラグメントシェーダは、問題は、定数についてわからないことIでintensity = 0.020.01され、私はそれは素晴らしい見えるようにする機能を追加しました。また、半径変数は画面の高さと幅の間の最大値になりました。

アップデート2:

私は最終的に次の式を選択している:

そして、オクルージョンマップと組み合わせ
void main() { 
    float dist = distance(vPosition, u_origin)/u_radius; 
    vec4 color = vec4((vColor.rgb)/(pow(dist, 2) + 0.01), vColor.a); 

    gl_FragColor = color; 
} 

(非照光場所を暗くする)同じ式に基づきます。

ambient + occlusion

+2

暗いバンドが幻想であること。あなたはどんなグラフィックスエディタでも値をチェックして、それらがより暗くないことを確認することができます:)現在、あなたはsRGBでレンダリングしていないようですが、そうすべきです。二次的なフォールオフのような他のものもおそらくそれを隠すでしょう。 – ybungalobill

答えて

2

あなたがライトをスプラットどのように非常に依存します。ここでは、最終的な出力があります。

など。

:あなたは二つの光を追加する場合は、このプロファイルを取得します

enter image description here

:あなたはすなわち、(中心からの距離に関して)光の明るさとそのようなものをいくつか切り捨て二次関数を使用している場合このプロファイルで

enter image description here

enter image description here

、あなたは明確な不連続を参照してください。この不連続性の原因は、元の関数の切り捨てです。したがって、画像内には、2つのライトの交点に明るい領域が生じるような、切り捨てられたライト関数があります(2次、線形など)。

これを解決するにはどうすればよいですか?物理的に正しい光分布は、(2Dであなたも線形減衰を主張できる)次の間隔で落ちるxは、光源からの距離である:

light = factor/x^2 

この機能には二つの問題があります。まず、コンパクトにサポートされていません。これは、無限大のスプラット(または少なくとも画面の大きさ)を描かなければならないことを意味します。これは大きな問題ではないかもしれません。あなたはまた、非常に小さくなるとすぐに光をカットすることができます。 2番目の問題はより深刻です。 x0になると(つまり、ライトポジションに直接向いている)、この値を計算することはできません(領域がない点にすべての光エネルギーが集中しているため、無限に近づく傾向があります)。したがって、実際にはライトマップで何をしたいかによって異なります。もちろん、あなたがepsilonは非常に少数である

light = factor/((x)^2 + epsilon) 

と同様に正則ことができます。あなたのシーンが上から見えるものであれば、このイプシロンは地上の光の高さ(四角形)になります。

enter image description here

ほら、不連続:その後、次のようなプロファイルを得るでしょう。しかし、これを達成するためにはフラグメントシェーダが必要になるでしょう。

あなたは物理的な正しさを気にしない場合は、ガウススプラットも見栄えの良い結果を与えるかもしれない:

light = factor * exp(-x^2/variance) 
+0

私はこれを達成するためにいくつかのシェーダを使用することを余儀なくされたと思う、それはよりよく見えるかどうかを確認するためにメッシュとシェーダを試してみる –

+0

私はあなたが私に与えた機能を使用しようとしました'factor'、 'variance'、' espilon'は、 'radius'と' distance'のパラメータに適用されます。 Thx –

+0

'factor'はちょうどスケールであり、通常は光の強度と相関します。 '分散(variance) 'はガウスの分散であり、光の焦点がどのように集中するかを指定します。いくつかのパラメータを試してみてください。 'radius^2/4'から' radius^2/9'までの範囲にあるものは良い結果をもたらすはずです。 'epsilon'は任意の数です。私が言及したように、あなたはそれを地上の光の仮想の高さに設定することができます。また、明るさが急激に落ちるのにも影響します。私はこの例で 'ε= 1'を使ったと思う。 –

関連する問題