2

私はエンジンを作成していて、シーンの「太陽」としてライト0を使用しています。太陽は指向性ライトです。

シーンのオルソ視点を設定してから、ライトを画面の「東」側(およびキャラクター)に設定します(x / yは平面地形の座標であり、正のzがカメラに面し、「高さ」を示します。 "地形上-シーンも回転してx軸のアイソメビューになります)。

ライトは0,0,0の「東」を輝いているように見えますが、キャラクターが移動してもシフトしません(CenterCameraは、提供された値の負の値に対してglTranslate3fを実行し、ワールド座標を指定してマッピングできるようにします)。つまり、私が西に移動するほど、それは常に暗く、光がありません。

    Graphics.BeginRenderingLayer();
    {
        Video.MapRenderingMode();

        Graphics.BeginLightingLayer( Graphics.AmbientR, Graphics.AmbientG, Graphics.AmbientB, Graphics.DiffuseR, Graphics.DiffuseG, Graphics.DiffuseB, pCenter.X, pCenter.Y, pCenter.Z );
        {
            Graphics.BeginRenderingLayer();
            {
                Graphics.CenterCamera( pCenter.X, pCenter.Y, pCenter.Z );
                RenderMap( pWorld, pCenter, pCoordinate );
            }
            Graphics.EndRenderingLayer();

            Graphics.BeginRenderingLayer();
            {
                Graphics.DrawMan( pCenter );
            }
            Graphics.EndRenderingLayer();
        }
        Graphics.EndLightingLayer();
    }
    Graphics.EndRenderingLayer();

Graphics.BeginRenderingLayer = PushMatrix、EndRenderingLayer = PopMatrixVideo.MapRenderingMode=正投影とシーン回転/ズームCenterCameraはX/Y / Zの反対に変換し、文字がX / Y/Zの中央に配置されるようにします。画面の中央。

何かご意見は?たぶん私はここで私のコードのいくつかを少し混乱させましたか?

照明コードは次のとおりです。

    public static void BeginLightingLayer( float pAmbientRed, float pAmbientGreen, float pAmbientBlue, float pDiffuseRed, float pDiffuseGreen, float pDiffuseBlue, float pX, float pY, float pZ )
    {
        Gl.glEnable( Gl.GL_LIGHTING );
        Gl.glEnable( Gl.GL_NORMALIZE );
        Gl.glEnable( Gl.GL_RESCALE_NORMAL );
        Gl.glEnable( Gl.GL_LIGHT0 );

        Gl.glShadeModel( Gl.GL_SMOOTH );

        float[] AmbientLight = new float[4] { pAmbientRed, pAmbientGreen, pAmbientBlue, 1.0f };
        float[] DiffuseLight = new float[4] { pDiffuseRed, pDiffuseGreen, pDiffuseBlue, 1.0f };
        float[] PositionLight = new float[4] { pX + 10.0f, pY, 0, 0.0f };
        //Light position of Direction is 5 to the east of the player.

        Gl.glLightfv( Gl.GL_LIGHT0, Gl.GL_AMBIENT, AmbientLight );
        Gl.glLightfv( Gl.GL_LIGHT0, Gl.GL_DIFFUSE, DiffuseLight );
        Gl.glLightfv( Gl.GL_LIGHT0, Gl.GL_POSITION, PositionLight );

        Gl.glEnable( Gl.GL_COLOR_MATERIAL );
        Gl.glColorMaterial( Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT_AND_DIFFUSE );
    }
4

2 に答える 2

3

各サーフェスに法線を指定する必要があります。(法線なしで)起こっているのは、指向性ライトが基本的にゼロの東のすべてを位置的に照らしているのに対し、そこにあるすべての法線は0,0,1(西を向いている)です。

私が知る限り、各頂点で法線を送信する必要はありませんが、GLはステートマシンであるため、法線が変更されるたびに変更するようにする必要があります。したがって、立方体に面をレンダリングする場合、「西」の面には1回の呼び出しが必要です。

glNormal3i(0,0,1);
glTexCoord..
glVertex3f...
glTexCoord..
etc.

xyzで整列された直角プリズムの場合、「整数」で十分です。6つの基本的な方向のいずれにも向いていない顔の場合は、それらを正規化する必要があります。私の経験では、クワッドがフラットでない限り、最初の3つのポイントを正規化するだけで済みます。これは、クワッドの最初の3つの辺によって形成される三角形の法線を見つけることによって行われます。

私が啓発した「法線の計算」に関するいくつかの簡単なヒントがあります。

これの2番目の部分は、指向性ライトであるため(W = 0)、プレーヤーの位置で再配置しても意味がないことです。光自体がカメラの後ろから放射されていて、常に正面から照らしたい(モデルのような)目の前のオブジェクトを回転させている場合を除いて、その位置はおそらく次のようになります。

float[] PositionLight = new float[4] { 0.0f, 0.0f, 1.0f, 0.0f };

または、GLx方向が東西方向として解釈されている場合(つまり、最初は南北を向いている場合)

float[] PositionLight = new float[4] { 1.0f, 0.0f, 0.0f, 0.0f };

コンセプトは、顔ごとのライトを計算することです。ライトが移動せず、シーン自体が移動しない場合(カメラがシーン内を移動するだけ)、方向の計算は常に正しいままです。法線が正確であれば、GLは特定の面に現れる光の強度を把握できます。

ここでの最後のことは、GLが自動的にシャドウを処理しないことです。基本的なGL_Lightは、一連の凸型の制御された照明には十分であるため、光(太陽など)を顔に適用する必要があるかどうかを判断する必要があります。場合によっては、これは単に顔が属するソリッドを取得し、「空」に到達する前に太陽の光のベクトルが別のソリッドと交差するかどうかを確認することです。

このためのシャドウマッピングだけでなく、ライトマップに関するものも探してください。

于 2012-03-29T14:42:40.677 に答える
2

多くの人をつまずかせる可能性があることの1つは、送信先の位置がglLightFv現在のマトリックススタックによって変換されることです。したがって、ライトをワールド座標の特定の位置に設定する場合は、カメラと投影マトリックスを設定して、glLightFv呼び出し時にマトリックススタックでアクティブにする必要があります。

于 2012-03-29T16:50:12.197 に答える