I’ve recently stumbled upon an extension document that contains some bits and pieces about a pedestrian approach to perspective correct texture mapping.
If we get screen coordinate inputs then in order to perspectively
correct data (eg texture), the input data currently has to be
specified in one of the following manners
- Specify all the data normally
eg.
glTexture2T(s, t);
and the coordinates as
glVertex4T(xw, yw, z*w, w);
or- Divide each data by w
eg.
glTexture4T(s/w, t/w, r/w, q/w);
and the coordinates as
glVertex3T(x, y, z);
I’ve been using approach number one for quite some time (for my emulation stuff).
I’ve got identity matrices on modelview, projection and texture stacks, nothing that could get in the way really. I submit 4d vertices with explicit w and xyz components premulted by w. This w value is determined by the needs of the texture unit rather than anything else, as incoming vertices are already projected to screen coordinates. Submitted texture coords are plain 2d actually, but for making this comparison I’ve extended them to 4d with z=0.0, w=1.0.
The results of this method look like this:
Approach number two looks a lot cleaner, is friendlier towards multitexturing (which can have different w per texture) and would really help avoiding z artifacts in multipass rendering (exact same z -> no fighting).
I’m also atm not concerned about color interpolation and the like, just the textures. So I implemented it. The only difference is this snippet, carried out per vertex:
float w=1.0f/oow; //one over w. like in 1/w dest->cx*=w; dest->cy*=w; dest->cz*=w; dest->cw*=w; dest->tx0*=w; dest->ty0*=w; dest->tz0*=w; dest->tw0*=w;
This ends up producing vertices where coordinate w is always 1.0.
Hah, works well in theory, but here’s the result:
This is an extreme example, most of the time it almost works. But I really don’t know how to improve that.
Looks like I’m losing too precision somewhere …
Well, at least in theory the parameters ending up in the texture sampler should be exactly the same.
So, what can I do?