Logarithmic Encoding
A
logarithmic depth value is
produced by encoding a negated (and therefore
positive)
eye-space
z value in the
manner specified by
encode
[
LogDepth.hs]:
The function is parameterized by a so-called
depth coefficient that is
derived from the far plane distance
as shown by depth_coefficient.
The inverse of encode is
decode, such that
for a given negated eye-space z,
z = decode d (encode d z).
A graph of the functions is as follows:
The
io7m-r1 package
uses a slightly modified version of the encoding function that clamps
the original
z value to the range
[0.000001, ∞]. The reason for this
is that
log2 (0) is undefined, and
so attempting to derive a depth value in this manner tends to cause
issues with triangle clipping. The encoding function is also separated
into two parts as a simple optimization: The encoding function contains
a term
z + 1.0, and this term can
be calculated by a
vertex shader and
interpolated. The actual functions as implemented are given by
[
LogDepth.p]:
A fragment shader can use
encode_full
to compute a logarithmic depth value from a given positive eye-space
z value. Alternatively, a vertex
shader can compute the
z + 1.0
term
r from a non-negated eye-space
z
value, and pass
r to a cooperating
fragment shader which then finishes the computation by applying
encode_partial to
r. When performing
position reconstruction
during
deferred rendering, the original
eye-space
z value of a fragment is
retrieved by negating the result of
decode
applied to a given logarithmic depth sample.
The original derivation of the encoding and decoding functions as
described by Brano Kemen used the w component
of the resulting clip-space coordinates. Unfortunately, this does not
work correctly with orthographic projections, as the typical orthographic
projection matrix will produce clip-space coordinates with a
w component always equal to
1. Aside from the effects that this will
have on depth testing (essentially mapping the depth of all fragments to the
far plane), it also makes position reconstruction impossible as the original eye-space
z value cannot be recovered.
Instead, the io7m-r1 package uses
the negated eye-space z value directly
in all cases.