Depth ranges allow (or force) the computation of z-buffer depths to fit into specified ranges. The depth range of the entire scene is parameterized between 0 and 1. Individual depth ranges may be specified.
The depth range = ( xxx, yyy ) option requires that “xxx and yyy should be floating point values such that 0 <= xxx <= yyy <= 1” according to the documentation.
Although it’s valid to use xxx==yyy, this effectively forces all of the underlying geometry to have the same depth values. Something with an explicit depth value < the min will be set to the min. and an explicit value > the max will be set to the max. When xxx==yyy, general displacements of -8 and +8 will effectively be considered the same value.
One use case specifies one depth range for geometry under a specific segment hierarchy and another depth range another portion of the segment hierarchy. This ensures the two portions of the hierarchy are properly ordered front to back.
The overall parameterized depth range [0, 1] gives the context for understanding displacement values, their sign and units.
The displacement units come from the fact that there are 2^24 (24-bit integer depth and 8-bit stencil) discrete z-depths available in the parameterized depth range [0, 1]. Therefore, in the range [0.01, 0.1] there are about 1.5M buckets (or ~11.1% of 2^24).
Displacement values can be positive or negative. Negative displacement values move objects closer to the camera. Positive values move objects farther away.
In addition to considering the depth of 3D geometry in a scene, displacement values may be combined within depth ranges. The order of objects in the z-buffer considers all of these factors. The z values for objects are computed and then displacement values are applied. The resulting depth values (after clipping) then define the overall minimum and maximum depth range limits. This is mapped linearly to the parameterized depth range space 0, 1. Objects with a specified depth range have their z values mapped to that depth range.
What?! Displacement values are not guaranteed to control the depths of rendered objects?
Consider an example scene containing two pieces of geometry: a polygon and text. Assume the geometry of the polygon and text lie in the same (world space) plane and they are in the same depth range [0.01, 0.1]. The polygon is given a displacement of -1 and the text is given a displacement of -18. Generally, this means the text should be in front of the polygon given that it is moved closer to the eye than the polygon.
However, if their common depth range is fairly narrow, it may force the text and the polygon to be coincident depth-wise given the small difference in their displacement.
This unexpected result is similar to the challenge of floating point comparison. If the depth range is too narrow and the difference in general displacement is not large enough to distinguish between the two geometric entities after processing their depths, the polygon may appear in front of the text. Recall the computation goes like this: the z values for objects are computed and then displacement values are applied. The resulting depth values (after clipping) then define the overall minimum and maximum depth range limits. This is mapped linearly to the parameterized depth range space, in this case [0.01, 0.1]. Objects with a specified depth range have their z values mapped to that depth range.
Here’s how you could roughly determine the difference between two displacement values, d, that would reliably determine the z-depth order:
e = the desired offset between distinct floating point numbers,
b = max end of depth range,
a = min end of depth range
d = (e * 2^24) / (b - a)
The value of e should be somewhere in the range of 5e-7 (or larger) to ensure two floating point numbers will be distinct.
For the example depth range of [0.01, 0.1], d is about 93 to ensure you get 5e-7 between two identical depths (e.g. geometry in the same plane). Clearly, the displacement difference in this example is far too small since 17 < 93.
Each subwindow clears the z-buffer in the region where it is drawn (effectively drawing it’s background with a depth of 1). Any depth ranges in the scene graph hierarchy with that subwindow will get evaluated in that area using the camera set up for the subwindow. Basically, each subwindow should be independent.