Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在OpenGL中,如何使skybox不覆盖任何实体?_Java_Opengl_Lwjgl_Skybox - Fatal编程技术网

Java 在OpenGL中,如何使skybox不覆盖任何实体?

Java 在OpenGL中,如何使skybox不覆盖任何实体?,java,opengl,lwjgl,skybox,Java,Opengl,Lwjgl,Skybox,我正在用LWJGL(ThinMatrix目前的教程)用Java开发OpenGL游戏,我刚刚添加了我的skybox。然而,正如你从图片中看到的,它正在穿过树木,覆盖某个点后面的一切 以下是我对skybox的渲染代码: public void render(Camera camera, float r, float g, float b) { shader.start(); shader.loadViewMatrix(camera); shader.loadFogColor(

我正在用LWJGL(ThinMatrix目前的教程)用Java开发OpenGL游戏,我刚刚添加了我的skybox。然而,正如你从图片中看到的,它正在穿过树木,覆盖某个点后面的一切

以下是我对skybox的渲染代码:

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();
}
public void渲染(列表灯光、摄影机){
准备();
shader.start();
loadSkyColor(红色、绿色、蓝色);
shader.loadLights(灯光);
shader.loadViewMatrix(摄影机);
渲染器。渲染(实体);
shader.stop();
terrainShader.start();
地形阴影。loadSkyColor(红色、绿色、蓝色);
地形阴影。装载灯(灯);
terrainShader.loadViewMatrix(摄像头);
地形渲染器。渲染(地形);
terrainShader.stop();
渲染(相机、红色、绿色、蓝色);
地形;
实体。清除();
}

您可能想退房 该实例中的问题是skybox本身太小,并且与几何体相交


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

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

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

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


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

我对LWJGL不熟悉,你愿意写shader吗?在普通opengl中,您不必担心skybox多维数据集的大小,如果您愿意,它可以是
{1.0,1.0,1.0}
。您需要的是首先将您的相机放置在
{0.0,0.0,0.0}
处,并对场景中的所有内容进行skybox失败深度测试,您可以通过使skybox在标准化设备坐标中的
z
值为
1.0
来实现这一点

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

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

在透视图除以
w
之后,
z
将是
w/w
1.0

您可以做两件事

如果先绘制skybox,则可以禁用深度测试
glDisable(GL\u depth\u test)
或深度写入
glDepthMask(false)
。这将防止skybox绘制深度值,并且skybox将永远不会位于稍后绘制的任何对象的前面

如果您最后绘制skybox,您可以使用顶点坐标,将
w
-坐标设为0,从而使其实际上无限大。顶点
(x y z 0)
表示它是向量
(x y z)
方向上无限远的顶点。要防止剪裁,您必须启用深度夹持
glEnable(GL\u depth\u CLAMP)
这将防止OpenGl剪裁您的skybox面,并且您可以确保skybox始终处于最大距离,并且永远不会隐藏您之前绘制的任何内容


第二种方法的优点是在深度测试范围内。因为已经为场景编写了深度值,所以OpenGL管道可以跳过已被场景覆盖的skybox像素的计算。但是Skybox的片段着色器通常非常简单,所以不会有太大的区别。

是的,如果我向前移动相机,剪裁的模型就会出现。对于第二部分,是的,我试着先画它,但我发现它的效率稍低,因为它必须计算天空盒中的每个像素。我听说有一种方法可以将深度设置得尽可能远,但是找不到,所以我想我在这里可能会更走运。哦,openGL停止绘制对象的距离并不是那么远,因为当我禁用skybox时,我的视图会走得更远。如果有帮助的话,我可以给你看一个线框。基本上,在线框上,切点正好是skybox所在的位置,而不是OpenGL停止渲染的实际距离。这听起来像是同一个问题,那么,如果禁用skybox本身可以让更多的模型更远地绘制。听起来skybox太小了,需要放大以包围你的世界,而不是一小块。移除skybox并在线框上查看它,我非常肯定是skybox剪辑了树。我将如何缩放skybox?好的,这是一个我不知道的好技巧,它不需要更改任何opengl状态。好的,我看到我的答案中写了一些非常奇怪的东西,我现在修复了它。