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

你可以做两件事

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

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

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

于 2015-07-01T22:49:53.697 回答
2

我不熟悉LWJGL,你可以写shader吗?在普通的opengl中,您不必担心天空盒立方体的大小,{1.0, 1.0, 1.0}如果您愿意,可以。你需要首先将你的相机放置{0.0, 0.0, 0.0}在你的场景中并使天空盒无法通过深度测试,你可以通过将天空盒z在标准化设备坐标中的值设为 来实现1.0

在您的顶点着色器中执行此操作

gl_Position = (mvp_mat * vec4(xyz, 1.0)).xyww;

透视除以后wz将是w / w1.0

于 2015-07-01T21:52:50.103 回答
1

您可能想查看如何增加 openGL 停止绘制对象的距离(zfar/gluPerspective)? 这种情况下的问题是天空盒本身太小并且与几何体相交。

我还看到您首先渲染地形,然后是天空盒。我会尝试在那里翻转订单;先画天空盒再画地形。

于 2015-07-01T04:05:49.227 回答
1

首先,您应该移除天空盒并再次渲染场景以检查是否是天空盒剪辑了树。

如果是天空盒,只需缩放天空盒,使其包含地形中的所有对象。

如果不是,很可能是相机的问题(就像汉斯顿所说的那样)。您需要至少在天空盒后面设置远剪裁平面。也就是说,它应该大于天空盒的直径。

如果要缩放天空盒或任何其他对象,请使用 transformationMatrix。游戏引擎使用 4x4 矩阵来控制模型的大小、位置和旋转。您可以在源 TerrainRenderer.java 中的函数 loadModelMatrix 中看到示例。它创建一个变换矩阵并将其上传到着色器中。您应该做同样的事情,但将 scale 参数更改为您想要的。

于 2015-07-01T04:12:49.710 回答