1
\$\begingroup\$

This is a question that may have an answer that differs for vanilla desktop GL and GL ES 2.0 (and wishful thinking is that ES 3.0 would have the same answer as vanilla GL).

What I'm doing is rendering a cubemap with a FS quad and I'd like to know if there's a way to specify a constant depth value for an entire render call rather than to get involved at the fragment shader level, in hopes of chasing a little bit of performance as well as flexibility in that I can use the same shader for drawing to different const depth values.

As for why it might benefit performance, the note at the bottom here offers some ideas, such as early-z testing... I suppose realistically if I emit a constant distant fragment depth, then early-z can still happen while maintaining the flexibility of pixel-programmable depth in general (necessary for proper impostors as shown). In this case I may be splitting hairs unnecessarily at this point. However that note does mention that if I can avoid specifying gl_FragDepth, I should, but it'd be up to the driver whether it will do something smart if I e.g. set gl_FragDepth to a constant.

As an example I could render my 3D scene, then set depth draw value to maximum, keep depth test on, and then render a fullscreen quad for my cubemap skybox, and it would just do the right thing.

Otherwise, choices include:

  • render skybox first with depth testing switched off, then render scene
  • use a fragment shader for the skybox that specifies the requisite depth value (this may very well just be the answer)
\$\endgroup\$
1
  • \$\begingroup\$ According to sunsetlakesoftware.com/2011/05/08/… doing impostors is NOT simple when only on ES 2.0 on account of no EXT_frag_depth. Luckily I can adjust my full screen quad geometry for the skybox to get appropriate gl_FragCoord.z values. \$\endgroup\$
    – Steven Lu
    Commented Dec 28, 2014 at 1:03

1 Answer 1

2
\$\begingroup\$

Tile based GPUs usually prefers you to call glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) with depth at 1.0 in order to do a fast tile clear. Then render your skybox as an opaque quad with depth test "less" and no blending like any other opaque geometry.

The driver usually uses the glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) call to know it can start over with a completely fresh frame buffer, throwing away all previous data.

If you do not clear the color buffer it will need to reload the old color data from the previous frame buffer and it wont be able to pre-clear the internal tile rendering memory to a preset value (glClearColor, glClearDepth, glClearStencil) using specialized hardware.

If you need to render a primitive at a fixed depth force the z & w values in the vertex shader, do not do it in the pixel shader.

Setting the depth in the pixel shader, even to a constant value, forces pixel shader code to be run to calculate the depth rather than use the interpolator's special hardware/routine that is already optimized.

Even if a few drivers optimize for the very unique and extremely rare case of a forced const depth most drivers wont. For all the other devices you'll have to switch back to setting the depth in the vertex shader anyway which means a lot of wasted work just to save an insignificant fraction of gpu time on the skybox if anything at all.

Cheers,

\$\endgroup\$
3
  • \$\begingroup\$ Yeah I hadn't thought it through and realize i can avoid setting gl_FragDepth (not that I can even do that on a ES 2.0 context as no Apple devices even support EXT_frag_depth). This is interesting that there is a lot of implicit stuff happening based on the glClear. I suppose you're saying that the tile-based architecture will allow me to render my skybox first and I will still gain optimization such that hopefully it can skip some skybox fragments if some geometry to be rendered later covers those fragments! I'll try to render the skybox last to explicitly leverage depth test. \$\endgroup\$
    – Steven Lu
    Commented Dec 28, 2014 at 1:19
  • \$\begingroup\$ Exactly, the tile-based renderer will completely skip your skybox when a tile is completely covered with other opaque geometry. Just try rendering a thousand full-screen opaque polygons for fun, you'll see. \$\endgroup\$ Commented Dec 28, 2014 at 1:41
  • 1
    \$\begingroup\$ This rule of thumb applies to modern desktop hardware as well. Ever since the color buffer became compressed and hierarchical Z-buffering became a feature on commodity GPUs (this happened ~2002 on discrete desktop GPUs), clearing the buffers became very important to achieve optimal memory throughput. It's generally not advisable to skip clearing buffers or attempt to replace it with something that seems equivalent on any kind of modern GPU (tile-deferred or not). \$\endgroup\$ Commented Dec 28, 2014 at 4:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .