One plane is nearly free
Worth reading first: The precision a depth buffer has left · Four numbers and a window.
The precision a depth buffer has left works out what a depth buffer spends its codes on. Depth is stored as an affine function of one over the distance, so half the codes are spent before the harmonic mean of the two planes — twenty centimetres out of a kilometre for a typical pair — and the resolution goes as the square of the distance.
The formula it arrives at contains both planes, and the two do not enter it equally. This essay is about how unequally.
The answer is that one of them is nearly free and the other is the entire budget, and the two are not close.
The expression, written the useful way
The distance a surface must move to change its stored code by one, at distance z with b bits, is
which is the same expression the earlier essay derives, written as a difference of reciprocals rather than as (far − near)/(far·near). The two are the same number and the second form is NaN at far = ∞, which is the one value this essay most wants to evaluate it at.
Written that way the asymmetry is visible without any arithmetic. The near plane is small, so 1/near is large. The far plane is large, so 1/far is small. Their difference is dominated by the first term, and moving the second one around barely disturbs it.
By how much, exactly
For a camera with a tenth-metre near plane and a thousand-metre far plane, at fifty metres, with twenty-four bits:
- Push the far plane out by ten. The resolution changes by a factor of 1.00009 — nine thousandths of a per cent.
- Push it out by a thousand. 1.0001, a hundredth of a per cent.
- Take it to infinity. 1.0001, which is the same number, because infinity is where that ladder was going.
- Bring the near plane in by ten. A factor of 10.0009.
- Bring it in by a thousand. A factor of a thousand.
So the two planes are not two ends of the same choice. The near plane is the whole of the budget and the far plane is a rounding error on it.
The ratio between the two is the ratio of the reciprocals, which for this pair is ten thousand. That number is the whole essay: the near plane matters ten thousand times as much as the far one, for this camera, and the factor is computable for any other.
The practical form of that
A person tuning a renderer has two knobs and one of them does nothing.
The usual advice — pull the far plane in to improve depth precision — is very nearly worthless. Halving the far plane from a thousand metres to five hundred improves the resolution by a hundredth of a per cent and removes half the visible world.
The advice that works is the other one: push the near plane out. Moving it from a tenth of a metre to half a metre improves the resolution at every distance by a factor of five, and costs only the ability to draw things within half a metre of the eye — which for most cameras is nothing, because there is nothing there.
That asymmetry is not a rule of thumb. It is the reciprocal, and it can be quoted exactly for any pair.
It is worth noticing that the useful knob is also the one nobody thinks of as a knob. A near plane is usually set once, early, to whatever value makes nothing disappear, and then never touched — while the far plane is adjusted whenever the scene changes size. The habit is exactly backwards, and the reason it persists is that the far plane’s effect on what is visible is obvious and its effect on depth precision is not, so it gets adjusted for one reason and credited with the other.
And what the resolution is, in metres
The numbers are worth having in a unit rather than as a ratio, because the ratio makes the buffer sound either fine or hopeless depending on where the reader starts.
With a tenth-metre near plane, a thousand-metre far plane and twenty-four bits, the distance a surface must move to change its code by one is about fifteen thousandths of a millimetre at five metres, a millimetre and a half at fifty metres, and twenty-four millimetres at two hundred. The quadratic is doing all the work: two hundred metres out, two surfaces less than a centimetre apart share a code.
That is where the flickering comes from when two coplanar surfaces are drawn in the distance, and it is why the fix is a near plane rather than more bits. Doubling the bit depth buys a factor of two hundred and fifty-six; moving the near plane from a tenth of a metre to two and a half metres buys the same factor and costs nothing but the first two and a half metres.
Where the reciprocal comes from, and why it cannot be argued away
The asymmetry is not an artefact of a convention, and it is worth showing that it survives every reasonable alternative, because the first response to it is usually that the depth ought to be stored differently.
The depth row can only be affine in 1/z. That is not a design decision; it is forced. A projection matrix multiplies a homogeneous point and the divide happens afterwards, so whatever the third row computes is a linear function of (x, y, z, 1) divided by w — and w is z. A linear function of z over z is a + b/z, and there is nothing else available.
So the stored quantity is a + b/z, and the two constants are fixed by requiring the near plane to map to one end of the range and the far plane to the other. Solving those two conditions gives b = −2·far·near/(far − near), and the spacing of the codes in distance is the derivative of the inverse, which is where z² and the difference of reciprocals come from.
Every step of that is forced by the clipper, which needs points behind the eye to remain finite until after it has run. A pipeline that divided first could store any function of z it liked and would have no clip left to perform. That is the trade the divide is postponed is about, and the near plane’s dominance is the bill for it.
One consequence is worth stating before the matrix, because it settles a question a reader may already have. If the far plane barely enters the expression, what happens as it is removed altogether? Nothing dramatic — which is the next section, and is the reason the removal is worth doing.
The matrix with no far plane
Taking the far plane to infinity is not a limiting argument that has to be handled carefully. It is a matrix.
The two depth-row entries are A = (far + near)/(far − near) and B = −2·far·near/(far − near), and as far grows without bound A tends to 1 and B tends to −2·near. Substituting those gives a perfectly ordinary projection matrix whose clip-space depth is 1 − 2·near/z: it is −1 at the near plane and approaches 1 without ever reaching it, and nothing else in the matrix knows anything has happened.
Differenced against a finite far plane at a thousand metres, the two agree to a fraction of one code at the near plane and diverge only where there is nothing: the whole difference is one part in the far-to-near ratio, and that ratio is ten thousand here.
So a renderer that wants to draw an unbounded world does not need a compromise. It needs two entries changed, and the cost against a merely distant far plane is a hundredth of a per cent of the depth resolution.
Half the codes before the harmonic mean
The earlier rung’s headline result reads differently once the reciprocals are in view, and it is the same statement.
Half a buffer’s codes are spent before the harmonic mean of the two planes, which for a tenth of a metre and a thousand metres is about twenty centimetres. The harmonic mean of a small number and a large one is a little under twice the small one, whatever the large one is — so that twenty centimetres is a fact about the near plane and essentially nothing else.
Move the far plane to ten kilometres and the harmonic mean goes to 0.19999 metres. Move it to infinity and the harmonic mean is exactly twice the near plane, 0.2 metres, which is the limit the ladder was walking toward all along.
So “half the codes are spent in the first twenty centimetres” and “the far plane is nearly free” are one sentence. The buffer’s whole behaviour is set at the near end, and everything past a few multiples of the near plane is being described by the same asymptote.
What the far plane is actually for
If it costs nothing to move and nothing to remove, the question is why it is there.
Three answers, and the first is the only one that is about depth at all.
Bounding the codes. A depth code has to be a bounded quantity to be stored in a fixed number of bits, and the ordinary mapping bounds it by putting the far plane at a code of +1. The infinite version bounds it differently — the code approaches 1 asymptotically — which works and means a surface at ten kilometres and one at a hundred are separated by very few codes indeed. For a scene with real distant geometry that matters; for one whose far reach is sky it does not.
Culling. Anything beyond the far plane is discarded before it is drawn, which is work saved. That is an argument about cost and not about geometry, and this collection has nothing to add to it.
And fog, historically. A far plane at the distance the scene fades out is a way of not drawing what would be invisible. That is a decision about the picture rather than about the projection.
None of the three is a reason to keep the far plane close in the hope of buying precision, which is the reason it is usually cited for.
What a near plane costs that is not precision
Pushing the near plane out is free in the sense above and not free in every sense, and the other costs are worth stating so the advice is usable.
Things vanish. Anything nearer than the near plane is clipped, and for a camera that can approach a wall that is visible as the wall opening up. The usual symptom is a doorway a viewer can walk their eye through.
A near plane cuts objects rather than hiding them. A clipped solid is drawn with a hole where the plane cut it, exposing its inside — because a renderer draws surfaces and the surface that would have closed the cut is not there. That is a different-looking defect from the object disappearing, and it is the one that gets noticed.
And the frustum’s four sides are quoted on it. Moving the near plane rescales all four, which changes nothing about the camera — the sides are ratios and the near plane cancels — but does mean an implementation that stores the sides rather than the ratios has four numbers to update and can update three of them.
None of the three is about depth precision, and none of them is a reason to keep the near plane at a tenth of a metre when the nearest thing in the scene is two metres away.
Reversed depth, and why it is the other half of the same fact
There is a second repair which is worth naming because it attacks the same asymmetry from the floating-point side.
Storing the depth in a floating-point buffer with the near plane mapped to 1 and the far plane to 0 — reversed from the usual — puts the float’s own dense region, near zero, at the far end where the reciprocal has spread the codes thinnest. The two non-uniformities partly cancel, and the resulting precision is far better than either arrangement alone.
That is a different mechanism from anything above: it is about how a float distributes its representable values, not about the projection. This collection computes the projective content and stops there; how a particular number format spends its mantissa is a question about arithmetic, and the site says so rather than borrowing the authority of the geometry.
What the geometry does say is why the trick has anything to work with. The codes are unevenly spread because the row can only be affine in 1/z — which the divide is postponed shows is forced by the clipper needing points behind the eye to remain finite — and any repair has to be a repair to that unevenness. The near plane’s dominance and the reversed buffer’s usefulness are the same fact seen twice.
The same shape, elsewhere in the collection
A quantity dominated by one of its two inputs through a reciprocal is not a peculiarity of depth buffers, and this collection has met it twice before under other names.
Depth is a reciprocal is the stereo version: depth from a pair of views goes as one over the disparity, so a fixed error in what is read maps to an interval that is not symmetric and eventually is not bounded. The far end of a stereo pair’s range behaves exactly as the far end of a depth buffer’s does, and for the same algebraic reason.
How wrong a measurement can be is the metrology version: a height read from a cross-ratio divides by a quantity that goes to zero for a tall object, and the sensitivity grows as the square of the height.
All three are the same statement — a quantity read through a reciprocal has a conditioning that varies as the square of the answer — and all three have the same practical form, which is that the interesting question is never how accurate is it but where. A single accuracy figure for a depth buffer, a stereo pair or a photogrammetric height is a figure at one distance, and quoting it without the distance is quoting a constant for a function.
The check that this is conditioning rather than a bug
The claim that a quantity is dominated by one of its inputs is a claim about a derivative, and it is checked as a ladder rather than at a point.
Moving each plane by successive factors of ten and recording the resolution gives two sequences, and the requirement is that one be flat and the other be a straight line of slope one on log axes. Both are, and — the part that makes the far plane’s flatness a limit rather than a coincidence — the infinite far plane’s value sits at the end of the far sequence rather than off it, to within a part in a hundred thousand.
A single comparison at one ratio would have said the same thing and would have meant much less. The whole content of “nearly free” is that it stays nearly free as the factor grows, and a ladder is what says so.
Shares its objects with
Essays that name at least two of the same things, and that neither author linked.
- The near plane can be any plane — both name camera matrix, clip space, depth division, homogeneous coordinates, quantisation, view frustum
- A texture does not interpolate on the page — both name camera matrix, clip space, depth division, homogeneous coordinates
- A tile is an off-centre frustum — both name camera matrix, conditioning, view frustum
- What a flat map leaves alone — both name conditioning, homogeneous coordinates, projective limit
- What happens behind the eye — both name camera matrix, clip space, homogeneous coordinates
- A lens destroys the invariant — both name error propagation, sensitivity
Named objects
A flat tag is an object no other essay names yet.
Camera matrixClip spaceConditioningDepth divisionerror propagationHomogeneous coordinatesProjective limitQuantisationSensitivityView frustum