← Back to context

Comment by JKCalhoun

3 days ago

Subdivision is a good trick.

A friend was writing a flight simulator from scratch (using Foley and van Dam as reference for all the math involved). A classic perspective problem might be a runway.

Imagine a regularly spaced dashed line down the runway. If you get your 3D renderer to the stage that you can texture quads with a bitmap, it might seem like a simple thing to have a large rectangle for the runway, a bitmap with a dashed line down the center for the texture.

But the texture mapping will not be perspective (well, not without a lot of complicated math involved).

Foley and van Dam say — break the runway into a dozen or so "short" runways laid end to end (subdivide). The bitmap texture for each is just a single short stripe. Now because you have a bunch of these quads end to end, it is as if there is a longer runway and a series of dashed lines. And while each individual piece of the runway (with a single stripe), is not in itself truly perspective, each quad as it gets farther from you is nonetheless accounting for perspective — is smaller, more foreshortened.

Perspective correct texture mapping has been solved for quite some time without excessive subdivision.

It was avoided in the Foley and Van Dam days because it requires a division per rasterized pixel, which was very slow in the late 80s.

  • Back in the early 90s I did a version of Bresenham's algorithm that would rasterize the hyperbolic curves that perspective-correct texture mapping required. It worked correctly though the technique of just doing a division every n pixels and linearly interpolating won out in the end, if I recall.

  • You could also avoid divisions entirely, while still keeping 100% correct perspective, by "rasterizing" the polygon following the line of constant Z. You would save the divs, but then you would draw mostly outside the cache, so not a panacea, but for large surfaces it was noticeably nicer than divide-every-N-pixcels approximation.