2

動的視野を実装しています。照明の見栄えを良くし、壁にどのように影響するかを確認するために、シェーダーを使用することにしました。これが私が取り組んでいるシナリオです:http: //i.imgur.com/QxZVyo7.jpg

  1. 私は平らな床と壁の地図を持っています。ここにあるものはすべて2Dであり、3Dジオメトリはなく、壁を構成する2Dポリゴンのみがあります。

  2. ポリゴンの頂点を使用して影を落とし、表示可能な領域を定義します。(紫色の線は、次のステップで使用するマスクの一部です)

  3. シナリオの上に影を描くときにシェーダーを使用して、壁も隠されないようにします。

  4. このようにして、視野が変化するにつれて、影が壁に沿って動的に投影されます

これを実現するために、次のシェーダーを使用しました。しかし、これは一種のやり過ぎであり、本当に非効率的だと思います。

uniform sampler2D texture;
uniform sampler2D filterTexture;
uniform vec2 textureSize;
uniform float cellSize;
uniform sampler2D shadowTexture;



void main()
{
    vec2 position;
    vec4 filterPixel;
    vec4 shadowPixel;
    vec4 pixel = texture2D(texture, gl_TexCoord[0].xy );


    for( float i=0 ; i<=cellSize*2 ; i++)
    {
        position = gl_TexCoord[0].xy;
        position.y = position.y - (i/textureSize.y);
        filterPixel = texture2D( filterTexture, position );

        position.y = position.y - (1/textureSize.y);
        shadowPixel = texture2D( texture, position );

        if (shadowPixel == 0){
            if( filterPixel.r == 1.0 )
            {
                if( filterPixel.b == 1.0 ){
                    pixel.a = 0;
                    break;
                }
                else if( i<=cellSize )
                {
                    pixel.a = 0;
                    break;
                }
            }
        }
    }

    gl_FragColor = pixel;
}

マスク内の赤い色のピクセルを探すためだけに各フレーマーを繰り返すことは、非常に過負荷のように見えますが、シェーダーを使用して他の方法でこのタックを完了する方法がわかりません。

4

1 に答える 1

3

ここでの解決策は非常に単純です。シャドウマップを使用します。

あなたの状況は3Dではなく2Dかもしれませんが、基本的な概念は同じです。世界のある地点と「光源」(あなたの場合はプレイヤーキャラクター)の間に障害物のある表面があるかどうかに基づいて、領域を「シャドウ」したいとします。

3Dでは、シャドウマップは、光源の観点から世界をレンダリングすることによって機能します。これにより、値が(特定の方向の)ライトから最も近い障害物までの深さを表す2Dテクスチャが生成されます。シーンを実際にレンダリングするときは、現在のフラグメントの位置を2D深度テクスチャ(シャドウマップ)に投影して確認します。現在のフラグメントに対して計算する深度値が、シャドウマップの投影位置にある最も近い障害物よりも近い場合、フラグメントはライトから見えます。そうでない場合は、そうではありません。

2Dバージョンでも同じことを行う必要がありますが、ディメンションが1つ少なくなります。「光源」の観点から2Dワールドをレンダリングします。この場合の2Dワールドは、実際には邪魔なクワッドにすぎません(ラインポリゴンの塗りつぶしでレンダリングする必要があります)。視界を妨げるクワッドは、シャドウマップにレンダリングする必要があります。テクスチャへのアクセスは完全に不要です。必要な情報は深さだけです。シェーダーは色を書く必要さえありません。これらのオブジェクトをレンダリングするには、2D空間を1Dテクスチャに投影します。

これは次のようになります。

       X..X
XXXXXXXX..XXXXXXXXXXXXXXXXXXXX
X.............\.../..........X
X..............\./...........X
X...............C............X
X............../.\...........X
X............./...\..........X
X............/.....\.........X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Cキャラクターの位置です。ドットは規則的で邪魔にならない床です。sはX壁です。からの線はC、2D線をレンダリングするために必要な4つの方向を表します。

3Dでは、ポイントライトのシャドウマッピングを行うには、シーンを6回、6つの異なる方向にキューブシャドウマップの面にレンダリングする必要があります。2Dでは、シーンを4回、4つの異なる方向に4つの異なる1Dシャドウマップにレンダリングする必要があります。これには、1D配列テクスチャを使用できます。

シャドウマップを取得したら、シェーダーでそれらを使用して、フラグメントが表示されていることを検出します。これを行うには、ウィンドウスペースから、レンダリングした4つのビューの方向を表す4つの異なる投影への一連の変換が必要になります。フラグメントがターゲットに対してどこにあるかに基づいて、これらの1つだけが特定のフラグメントに使用されます。

これを実装するには、方向性のある「シャドウイング」の単純なケースを機能させることから始めます。つまり、位置を使用しないでください。ただの「光」の方向。これにより、2Dから1Dへの投影マトリックス、およびワールドスペースクワッドをカメラスペースに変換するための適切なカメラスペースマトリックスを開発する能力がテストされます。それをマスターしたら、さまざまなプロジェクションで4回作業を開始できます。

于 2013-03-27T12:42:34.713 に答える