2016-09-27 6 views
7

ピクセル化されたiOSアプリケーションでUnity3Dで使用するためのGLSLシェーダを作成しました。ピクセルライティングシェーダ

1)効果は、常に月に滞在していない、と 2)照明は、ピクセル化は見えません:それは ONE問題があります。

少し説明します。シェーダは、月が後ろにあるときに前景オブジェクトに照明効果を生じさせることを目的としています。そうように、私は通常(シルエットのような)すべての黒として表示されるスプライトを持っているが、月オブジェクトはそれに十分に近い場合には、テクスチャの詳細を明らかにする:

enter image description here

実際の私は一つだけのテクスチャを持つライトマップを持つことができるように、私はこのような効果をしていた理由がある

enter image description here

:(シェーダなし)スプライトは次のようになります。しかし、それには2つの問題があります:

1)私は画面の端に近づくにつれて、光の効果が月に正確に追いつかない。私はこれがTEXCOORD1変数の誤った使い方に関連しているかどうかはわかりません。私はスクリーン全体を覆うスプライトを作ったので、それが月の後にいかないかを見ることができます。私のテストシーンでの問題の写真を示します。黒い縞とアルファが付いたフルスクリーンのスプライトがあり、エフェクトがいつどこにあるのかを正確に表示できます。私は、このデシンクを取り除きたいのです。なぜなら、それは照明を非現実的に見せるからです。

enter image description here

2)生じた照明効果は非常に鋭いです - それは良くなり、各ピクセルはSpriteLampのように、個別に点灯していた場合、私は、と思います。私はそれがシェーダのフラグメント座標を丸めることと関係していることを知っていますが、実際に変数の値がシェーダ内にあるかどうかわからないので、正しく動作するようには見えません。

私は距離を丸くすることができますが、これは月からの距離に従っていますが、元のスプライトのピクセルには従いません。私はもっ​​とこのようなものです探しています何

enter image description here

...そこピクセレーションはあるが、我々はあなたが私の意味をキャッチした場合、ただ一つの画素がどうあるべきか全体でこの奇妙な曲線になってしまいます。元のテクスチャの個々のピクセルがどのように点灯しているかを確認します。

enter image description here

ここではシェーダ自体へのリンクです:http://pastebin.com/0zbqrP57。これはデフォルトのユニティスプライトシェーダですが、ほとんどの場合、SampleSpriteTexture関数の最後にいくつかのコードが追加されています。

実際のシェイダーを見るために使用できるユニティパッケージへのリンクです。シーンが再生されている間に月を動かしてみてください。

https://drive.google.com/open?id=0BxCQjUHiAAQWZGpPZ3R2SExTcXc

私の質問:あなたは彼らにこれらの問題、または解決策を解決する方法上の任意のアドバイスはありますか?

+2

私はあなたの問題を理解していますが、あなたはそれについて特定の質問をしませんでした。あなたはデシンクが起こる理由を理解しようとしていますか?回避策に関する提案を期待していますか?ここでの目的は何ですか?編集してください。 – XenoRo

+0

こんにちは、@ AlmightyR、提案に感謝します。私は提案と解決策を期待しています。私は質問を更新しました。目標は、問題2で効果を実装することです(現在の設定よりも見栄えがよい)ので、非同期の問題を解決してください。 – Catlard

+1

うわー、それは魅力のように機能します。ありがとうございます – Learner

答えて

2

OUT.worldSpacePosition = mul(_Object2World, IN.vertex); 

ため

OUT.worldSpacePosition = mul(_Object2World, OUT.vertex); 

を変更すると、月の紛失を修正する必要があります。私はこの思い付いた第二の問題については

aS = floor(aS * 100)/100; 
bS = floor(bS * 100)/100; 
float dist = sqrt((aS * aS) + (bS * bS)); 
float percentClose = 1 - (dist/_LightStrength); 
float rounded = floor(percentClose * 10)/10; 

if (color.r + color.g + color.b > 0) { 
    color.r = lerp(0, color.r, rounded); 
    color.g = lerp(0, color.g, rounded); 
    color.b = lerp(0, color.b, rounded); 
} 

私はあなたがif文をドロップすることができると思うとだけにlerps:

aS = floor(aS * 100)/100; 
bS = floor(bS * 100)/100; 
float dist = sqrt((aS * aS) + (bS * bS)); 
float percentClose = 1 - (dist/_LightStrength); 
float rounded = floor(percentClose * 10)/10; 
color.rgb *= rounded; 

しかし、この場合には、あなたの側でそれをテストする必要がありますパフォーマンスが向上するかどうかを確認してください。

+0

最初の修正は素晴らしいです!なぜ違うのか説明できますか?しかし、ピクセルライティングスキームは、私が探していたものではありません。より具体的ではないことを申し訳ありません。私は質問を更新しました。 *弓* – Catlard

+0

明確にするために、私は条件式をどうやって/どのように取り除いているのか理解していますが、なぜIN.vertexはOUT.vertexと違うのですか?そこには何が起こっているのですか? 更新情報を確認しましたか?あなたが本当に理解していなければ、私に知らせてください。 – Catlard

+0

なぜそれが違うのか本当に分かりません。 OUT.vertex = UnityObjectToClipPos(IN.vertex);を 'OUT.vertex = IN.vertex; 'に変更してUnityPixelSnap()を取り除いても正しく動作しません。多分もっと経験豊富な人がこれを説明するかもしれない。 ユニティパッケージを再度アップロードできますか?私は月の材料やスプライトを壊してしまった。 – Krajca