4

I am working on an OpenGL game in Java with LWJGL (ThinMatrix's tutorials at the moment) and I just added my skybox. As you can see from the picture, however, it is clipping through the trees and covering everything behind a certain point.

Here is my rendering code for the 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());
}

also if it is needed, here is my code for my master renderer:

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();
}

Image

Meeesh
  • 992
  • 1
  • 8
  • 15

4 Answers4

7

There are two things you can do

If you draw your skybox first, you can disable your depth test glDisable(GL_DEPTH_TEST) or your depth write glDepthMask(false). This will prevent that your skybox draws depth values, and the skybox will never be in front of anything that will be drawn later.

If you draw your skybox last, you can make it literally infinitely big by using vertex coordinates with a w-coordinate as 0. A vertex (x y z 0) means it is a vertex infinitely far in the direction of the vector (x y z). To prevent clipping, you have to enable depth clamping glEnable(GL_DEPTH_CLAMP) this will prevent OpenGl to clip away your skybox faces, and you are sure that the skybox is always at the maximum distance and will never hide anything you have drawn earlier.

the advantage of the second method is within the depth test. Because you already have a depth values written for your scene, the OpenGL pipeline can skip the calculation of the skybox pixels that are already covered by your scene. But the fragment shader for skyboxes is usually very trivial, so it shouldn't make that much of a difference.

Arne
  • 7,921
  • 9
  • 48
  • 66
2

I am not familiar with LWJGL, are you alllowed to write shader? In plain opengl, you don't have to worry about the size of skybox cube, it can be {1.0, 1.0, 1.0} if you like. What you need is first place your camera at {0.0, 0.0, 0.0} and make skybox fail depth test against everything in your scene, you can achieve that by making the skybox's z value in normalized device coordinate be 1.0.

Do this in your vertex shader

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

after the perspective divide by w, z will be w / w or 1.0.

yngccc
  • 5,594
  • 2
  • 23
  • 33
  • ok, that's a nice trick that I did not know, that does not require to change any opengl state. – Arne Jul 01 '15 at 23:51
1

You might want to check out How can I increase distance (zfar/gluPerspective) where openGL stops drawing objects? The problem in that instance is that the skybox itself was too small and intersecting with the geometry.

I also see that you're rendering your terrain first, and then your skybox. I would try flipping the order there; draw the skybox first then the terrain.

Community
  • 1
  • 1
Brandon Haston
  • 434
  • 3
  • 5
  • Yeah, If I move the camera forward, the clipped models come into view. With the second part, yeah I tried to draw it first, but I found it to be a little less efficeint because then it has to calculate for every pixel in the skybox. I heard there was a way to set the depth to be as far a way as possible, but wasn't able to find it so thought I'd maybe get more luck here. – Meeesh Jul 01 '15 at 04:10
  • Oh, it isn't that distance where openGL stops drawing objects because when I disable the skybox, my view goes a lot farther. I can show you a wireframe of it if it helps. Basically on the wireframe the cut off point is just where the skybox is, not the actual distance OpenGL stops rendering I think. – Meeesh Jul 01 '15 at 04:13
  • It sounds like the same issue, then, if disabling the skybox itself lets more models further away to draw. It sounds like the skybox is just too small and needs to be scaled up to surround your world rather than a small chunk of it. – Brandon Haston Jul 01 '15 at 16:49
1

First, you should remove the skybox and render the scene again to check if it is skybox that clip the tree.

If it is skybox, simply scale the skybox to make it contain all the object in the terrain.

If not, it is likely to be the problem of camera (like Hanston said). You need to set the far clipping plane at least behind the skybox. That is, it should be larger the diameter of your skybox.

If you want to scale the skybox or any other object, use the transformationMatrix. the game engine use a 4x4 matrix to control the size, location and rotation of the model. you can see example in source TerrainRenderer.java, at function loadModelMatrix. It create a transform matrix and uploads it into the shader. You should do the same thing, but change the scale parameter into what you want.

laugher
  • 33
  • 8
  • Removing the skybox and viewing it on wireframe, I'm pretty positive it is the skybox that clips the tree. How would I scale the skybox? – Meeesh Jul 01 '15 at 04:14