4

私はLWJGL(現時点ではThinMatrixのチュートリアル)を使用してJavaでOpenGLゲームに取り組んでおり、スカイボックスを追加しました。ただし、写真からわかるように、木々を切り裂き、特定のポイントの背後にあるすべてを覆っています。

スカイボックスのレンダリング コードは次のとおりです。

public void render(Camera camera, float r, float g, float b) {
    shader.start();
    shader.loadViewMatrix(camera);
    shader.loadFogColor(r, g, b);
    GL30.glBindVertexArray(cube.getVaoID());
    GL20.glEnableVertexAttribArray(0);
    bindTextures();
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, cube.getVertexCount());
    GL30.glBindVertexArray(0);
    shader.stop();
}

private void bindTextures() {
    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, texture);
    GL13.glActiveTexture(GL13.GL_TEXTURE1);
    GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, nightTexture);
    shader.loadBlendFactor(getBlendFactor());
}

また、必要に応じて、マスター レンダラーのコードを次に示します。

public void render(List<Light> lights, Camera camera){
    prepare();
    shader.start();
    shader.loadSkyColor(RED, GREEN, BLUE);
    shader.loadLights(lights);
    shader.loadViewMatrix(camera);
    renderer.render(entities);
    shader.stop();
    terrainShader.start();
    terrainShader.loadSkyColor(RED, GREEN, BLUE);
    terrainShader.loadLight(lights);
    terrainShader.loadViewMatrix(camera);
    terrainRenderer.render(terrains);
    terrainShader.stop();
    skyboxRenderer.render(camera, RED, GREEN, BLUE);
    terrains.clear();
    entities.clear();
}

画像

4

4 に答える 4

7

あなたができることは2つあります

最初にスカイボックスを描画する場合は、深度テストglDisable(GL_DEPTH_TEST)または深度書き込みを無効にすることができますglDepthMask(false)。これにより、スカイボックスが深度値を描画するのを防ぎ、スカイボックスが後で描画されるものの前に表示されることはありません。

スカイボックスを最後に描画する場合、 -座標をw0 として頂点座標を使用することにより、文字通り無限に大きくすることができます。頂点(x y z 0)とは、ベクトルの方向に無限に遠い頂点であることを意味し(x y z)ます。クリッピングを防ぐには、深さのクランプを有効にする必要があります。glEnable(GL_DEPTH_CLAMP)これにより、OpenGl がスカイボックスの面を切り取るのを防ぎます。スカイボックスは常に最大距離にあり、以前に描いたものを決して隠しません。

2 番目の方法の利点は、深度テスト内にあります。シーンに深度値が既に書き込まれているため、OpenGL パイプラインは、シーンで既にカバーされているスカイボックス ピクセルの計算をスキップできます。しかし、スカイボックスのフラグメント シェーダーは通常非常に簡単なので、それほど大きな違いはありません。

于 2015-07-01T22:49:53.697 に答える
1

最初に、スカイボックスを削除し、シーンを再度レンダリングして、ツリーをクリップするスカイボックスであるかどうかを確認する必要があります。

スカイボックスの場合は、スカイボックスをスケーリングして、地形内のすべてのオブジェクトが含まれるようにします。

そうでない場合は、カメラの問題である可能性があります(ハンストンが言ったように). 少なくともスカイボックスの後ろにファー クリッピング プレーンを設定する必要があります。つまり、スカイボックスの直径より大きくする必要があります。

スカイボックスまたはその他のオブジェクトをスケーリングする場合は、transformationMatrix を使用します。ゲーム エンジンは 4x4 マトリックスを使用して、モデルのサイズ、位置、および回転を制御します。ソース TerrainRenderer.java の関数 loadModelMatrix で例を見ることができます。変換マトリックスを作成し、シェーダーにアップロードします。同じことを行う必要がありますが、スケール パラメーターを必要なものに変更します。

于 2015-07-01T04:12:49.710 に答える