在 OpenGL 中,如何使我的天空盒不覆盖我的任何实体?

Mee*_*esh 4 java opengl lwjgl skybox

我正在使用 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());
}
Run Code Online (Sandbox Code Playgroud)

如果需要,这里是我的主渲染器的代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

图片

Arn*_*rne 7

你可以做两件事

如果您先绘制天空盒,则可以禁用深度测试glDisable(GL_DEPTH_TEST)或深度写入glDepthMask(false)。这将防止您的天空盒绘制深度值,并且天空盒永远不会在以后绘制的任何东西之前。

如果你最后绘制天空盒,你可以通过使用顶点坐标将w-coordinate 设为 0来使它无限大。顶点(x y z 0)意味着它是一个在向量方向上无限远的顶点(x y z)。为了防止剪裁,您必须启用深度夹紧,glEnable(GL_DEPTH_CLAMP)这将防止 OpenGl剪掉您的天空盒面,并且您确保天空盒始终处于最大距离并且永远不会隐藏您之前绘制的任何内容。

第二种方法的优势在于深度测试。因为您已经为场景编写了深度值,所以 OpenGL 管道可以跳过场景已经覆盖的天空盒像素的计算。但是天空盒的片段着色器通常非常简单,所以它不应该有太大的不同。