Pass only if current depth is 1.0

Started by
16 comments, last by Kryzon 13 years, 9 months ago
I am drawing the sky last because it is more efficient than drawing it first. However, I'm not sure how to guarantee that the sky will be drawn behind everything. Is there a way to either tell OpenGL to set the fragment depth to 1, other than by modifying depth in the fragment shader (which, as I understand, is inefficient because it doesn't allow OpenGL to reject fragments before the fragment shader runs, which would defeat the purpose entirely), or to always reject fragments if there's already something written (depth < 1)?
Advertisement
-You could first render the sky with depth writing disabled. By not writing any depth, all object rendered after the sky will be in front of it.
- Or just make the sky shpere/box/drome very very large.

ps: glDepthMask(bool flag) is the function you need to disable/enable depth writing (at least in openGL 1.0/2.0 don't know about 3+). (true is enable write, false is disable)
You could play with the depth ranges. Use something like 0-0.99 for the scene, and 0.99-1.0 for the sky.

I don't know, maybe this can only be set with fixed pipeline.
Hmm, perhaps even 1.0-1.0 will do the trick. From http://www.opengl.org/sdk/docs/man/xhtml/glDepthRange.xml:
Quote:It is not necessary that nearVal be less than farVal. Reverse mappings such as nearVal = 1 , and farVal = 0 are acceptable.

So 1.0-1.0 must at least be a valid setting. I'll see what it does. (If it works, this seems like a more reliable way of drawing the skybox than just making it really big.)
Assuming you're using the programmable pipeline, I *believe* you can set the fragment w component equal to the fragment z (just make the swizzle '.xyzz') in the vertex shader, which, when performing the perspective divide, will force the vertex/polygon to reside on the far plane. From there, just ensure that depth testing is enabled and optionally disable depth writes.

EDIT: Man, swinging 0 for two that day. The post now contains the correct info/formula.

[Edited by - InvalidPointer on July 22, 2010 12:50:35 PM]
clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.
You could disable both depth writing and depth testing and use the stencil buffer to draw your skybox.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Quote:Original post by InvalidPointer
set the fragment w component to 0 in the vertex shader, which, when performing the perspective divide, will force the vertex/polygon to reside on the far plane.
QFE -- you actually want to set z=w, but this is the recommended way to do skyboxes. Messing with the depth test (other than enabling/disabling it) isn't necessarily a good idea, because (depending on how you do it) it may disable the hierarchical depth buffering built into modern GPUs.
Ah, that makes sense, thanks! So, in the vertex shader then, is the way to do this to alter the perspective matrix? Or does anyone know if there's a function/output (in Cg, which is what I'm using) which allows the w value to be overridden?

EDIT: Oh wow, that was a dumb question. The output position is (x, y, z, w)! Haha.

EDIT2: Hmm, if w = 0, then you're going to be dividing x, y, and z by 0... I take it OpenGL doesn't mind in this case?
Quote:Original post by Gumgo
EDIT2: Hmm, if w = 0, then you're going to be dividing x, y, and z by 0... I take it OpenGL doesn't mind in this case?
Don't set w to 0. Set z to whatever w is.
Quote:Original post by Sneftel
Don't set w to 0. Set z to whatever w is.
Extra QFE:
vertPos = ...;
vertPos = vertPos.xyzz;//copy z over w

This topic is closed to new replies.

Advertisement