Sign in to follow this  
arnero

perspective correct texture mapping reloaded

Recommended Posts

Recently a lot of videos from 3do and atari jaguar pop up on youtube. That got me thinking about perspective correct texure mapping again. Google values a tutorial by Chris Hecker very high. Hardware seem to do it like MS Flight Simulator 3 or so: Tiles. Software does it with spans with 2^x length.

Tiles are independent from orientation but look bad on the horizon. Doom looked good there. It uses const Z spans. So I (like others) figured the best way to interpolate would be to choose vertical or horizontal spans, or diagonals, depending on the orientation. In fact the best direction for the span is where the  delta_Z * delta_screen_distance is at minimum. So with 3 cases we covered most. Probably we could add 5 more by sitting down and doing the math. Anyhow, what I want to conclude from this is: We need integer vertex coordinates on the screen. I was dabbling with floating point, but for that I would have to draw all tris from top to bottom. Same with scanline rendering. Does not fit. But luckyly, scanline rendering is dead, and screen vertex coordinates are integers / fixed point in most implementations.

So we have spans where z is varrying slowly. Why not aim for perfection and somehow use the last value of z and the new of 1/z to get a good starting value for the 1/z calculation. I figured out that extrapolation is not stable. All algorithms use interpolation on all stages. So the way to get perfect 1/z with some speed up by coherence is to subdivde each span into a binary tree (node based). In software working with such a tree would be a nightmare, but in HW this only means some gates. For a mid point we take the mid (mean) of the surounding Z (left=l and right=r) and the sourrounding 1/Z as a guess. Z * 1/Z = 1 . We multipy out and find that we are still left with a product before we can even start to the division for the small correction value (Z_r-Z_l)*((1/Z)_l-(1/Z)_R) + Z_correction*(1/Z)= 1. ( r= right, and l=left) (1/Z is usually written as W).

But anyhow: quotient with a low number of digits => fast division  ( the number of digts is often 0 or 1 in the leafs something which can be looked up in a single cycle using the msb of the mantissa)

In the product the factors are delta values => also somewhat small => low energy consumption in CMOS multiplier.
The product between 1/Z and U/Z and V/Z may even cost more. Doing this in the tree and multiplying out here also only deltas are multiplied. In the leafes of the tree, the deltas are the smallest. Same for RGB (texture caching?).

With perspective correction I always feared to overflow the texture buffer. But as said, we are doing only interpolation. So no overflow here. Furthermore, a division looks horrible in fixed point (and we use fixed point for the edges), but for Z, U and 1/Z floating point is much better. Division becomes negation on the exponent, and the mantissa only looses about 1 bit precision. Then with subtexel precision we only overflow out of the texture by max 1 texel. For first gen 3d (not much memory)(in an alternative universe) I would love the texels to precisely match many edges. Saturation (cheap in HW) takes care of the handful of pixels slightly overflowing.

I wonder how you guys prove the correctness of complicated shaders. Phong shading correctness is already a miracle to me. Raytracers anyone? Sorry that this is a zero-replies follow up from 2016.

Share this post


Link to post
Share on other sites

Raytracing is common. EG was used for reference against Respawns reciprocol GGX/Oren-Nayar diffuse brdf for Titanfall 2. They massively oversampled a random heightfield with a directional light using raytracing, then compared that to an equivalent roughness diffuse material using their brdf to try and get the latter to match the former, as theoretically that's exactly what you'd want it to do.

Share this post


Link to post
Share on other sites

So raytracing is still in use. A million rays shot every second around the world. If i test for ray triangle intersection I do it individually for each edge. There is rounding involved so that effectivey these edges do not meet at the vertices. So with a bright background and a hightfield before that, triangles nearly hit from the side may lead to rays passing through the heightfield. I guess with current precision even in realtime applications no one notice a wrong pixel per hour.

Share this post


Link to post
Share on other sites

Historically I was wondering if someone could have come up with cheap realtime 3d before the ps. But then apparently one needs a minimum triangle count to make a game. What if there was a graphics adapter putting out 1024x200px on a cart rendering subpixel precision textured triangles like sprites (max 16 tris per scanline). Tris would be large to keep the count low => need to be perspective correct. It would have a smooth look. It is easy on the hardware. It would clip small or distant tris to keep the count low and thus would have had a very special look.

Last application for software rendering was the GBA. In 20 years 3d accelerators will be something only a minority knows how it works.

Share this post


Link to post
Share on other sites

Tiles are independent from orientation but look bad on the horizon.

I don't think it looking bad has to do with rasterization method.

If you want a pretty good article on non-span based rasterization I remember this one:  http://forum.devmaster.net/t/advanced-rasterization/6145

I don't remember whether or not it covers texture mapping but it does cover rasterization.

Just thought you might find it interesting.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this