0

私は小さなマインクラフトのクローンをコーディングしたい. ここで、いくつかの単純な照明を挿入しようとしましたが、結果は非常に悪いです。私はそれについて多くのことを読んで、結果なしでさまざまな解決策を試しました。

それが私が得たものです。

初期化中:

    GL11.glViewport(0, 0, Config.GAME_WIDTH, Config.GAME_HEIGHT);
    GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
    GL11.glLoadIdentity(); // Reset The Projection Matrix

    GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
    GL11.glLoadIdentity(); // Reset The Modelview Matrix

    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glEnable(GL11.GL_CULL_FACE);
    GL11.glFrontFace(GL11.GL_CCW);

    GL11.glLightModeli(GL11.GL_LIGHT_MODEL_LOCAL_VIEWER, GL11.GL_TRUE);
    GL11.glEnable(GL11.GL_LIGHTING);
    GL11.glEnable(GL11.GL_LIGHT0);

    FloatBuffer qaAmbientLight  = floatBuffer(0.0f, 0.0f, 0.0f, 1.0f);
    FloatBuffer qaDiffuseLight  = floatBuffer(1.0f, 1.0f, 1.0f, 1.0f);
    FloatBuffer qaSpecularLight = floatBuffer(1.0f, 1.0f, 1.0f, 1.0f);

    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, qaAmbientLight);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_DIFFUSE, qaDiffuseLight);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_SPECULAR, qaSpecularLight);

    FloatBuffer qaLightPosition = floatBuffer(lightPosition.x, lightPosition.y, lightPosition.z, 1.0f);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, qaLightPosition);

だから今、各レンダリングの前に私はこれを試しました:

    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glClearColor(0.0f, 100.0f, 100.0f, 1.0f);
    GL11.glShadeModel(GL11.GL_FLAT);
    GL11.glLoadIdentity();
    FloatBuffer qaLightPosition = floatBuffer(lightPosition.x, lightPosition.y, lightPosition.z, 1.0f);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, qaLightPosition);

    FloatBuffer ambientMaterial = floatBuffer(0.2f, 0.2f, 0.2f, 1.0f);
    FloatBuffer diffuseMaterial = floatBuffer(0.8f, 0.8f, 0.8f, 1.0f);
    FloatBuffer specularMaterial = floatBuffer(0.0f, 0.0f, 0.0f, 1.0f);


    GL11.glMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT, ambientMaterial);
    GL11.glMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE, diffuseMaterial);
    GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SPECULAR, specularMaterial);
    GL11.glMaterialf(GL11.GL_FRONT, GL11.GL_SHININESS, 50.0f);

もちろん、これは多くのコードではありませんが、これはすべて照明に関するものです。私は間違いを犯しましたか?OpenGL は、ライティングとシャドウイングに関して DirectX ほど優れていないことを読みました。

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

http://img199.imageshack.us/img199/7014/testrender.png

見栄えを良くするためのヒントを誰か教えてもらえますか?

素晴らしいブロックの風景を含む投稿を 1 つ見つけました。 http://i.imgur.com/zIocp.jpg それがどのように見えるべきか:)

4

2 に答える 2

4

見栄えを良くするためのヒントを誰か教えてもらえますか?

プログラム可能なパイプラインを使用する場合、OpenGL も DirectX もライティングとシャドーイングとは何の関係もありません。法線は、ライティングの計算に使用できる別の頂点属性になります。固定機能は古く、推奨されていないため、強制的に使用しない場合はお勧めしません。

シェーダーへの変更はそれほど難しくなく、固定パイプラインに制限されることもありません。その後、ライティングの計算方法を完全に制御でき、より多くのデバッグ情報を簡単に出力できます (法線に基づいてサーフェスをカラーリングするなど)。

それはそれがどのように見えるべきかです:)

投稿した画面には、アンビエント オクルージョンも表示されています。シェーダーなしでこの効果を実現するのは非常に難しく、努力する価値はありません。

私はたまたま同様のプロジェクトを自分で行っています。それがオープンソースで公開されていなければ、私はそれについて言及しません。サンプル結果は次のとおりです。

ミニクラフトスクリーン

ライティング シェーダー コードはこちらにあります

リンクが腐らないように抜粋を投稿します。

float CalcDirectionalLightFactor(vec3 lightDirection, vec3 normal) {
    float DiffuseFactor = dot(normalize(normal), -lightDirection);

    if (DiffuseFactor > 0) {
        return DiffuseFactor;
    }
    else {
        return 0.0;
    }
}

vec3 DiffuseColor = Light0.Color * Light0.DiffuseIntensity * CalcDirectionalLightFactor(Light0.Direction, normal);
于 2013-04-07T16:42:53.887 に答える
1

Bartekの答えは良いものです。独自のシェーダーを作成する道をたどり、OpenGl がシャドウイングとライティングに提供するものを理解し、古い非推奨のライティング モデルに依存しないようにする必要があります。glEnable(LIGHTING_AND_SHADOWING) はもっと複雑です。

ただし、コードをいじって、バイナリの黒/白から色が変化するのを確認したいだけの場合は、qaSpecularLight をオフにすることが考えられます (これにより、"マット" ルック) を調整し、スムーズ シェーディングの glShadeModel 設定を調整します。

それはいくらか役立つはずですが、目標に到達するまでには至りません。Bartek の提案されたパスに従ってください (または同様のアイデアについてはグーグルで検索してください)。

于 2013-04-07T17:07:24.237 に答える