Skip to main content
GameDev.net gamedev.net
🔒 Locked

Texture Swimming

Started by dega512 Apr 8, 2006 at 6:04 PM 8 replies 1.8k views
Original Post
dega512
dega512
I have just written a rasterizer and I have an interesting problem. When I rotate polygons with textures on them, the texture appears to swim up and down. I am pretty sure this problem is caused by subpixel/subtexel accuracy (I don't have it). I have tried to implement it but it either does not work or screws everything up. So with that said, any ideas on how to get rid of my fun "extra" feature? Thanks, -dega P.S. If you want my current code (Java) I'll send it to you.
It's easy as 01, 10, 11
Antheus
Antheus
If it jumps up and down by 1 pixel only, it could be aliasing artefacts. Other than that, are you using rounding anywhere in there, or just integer only algorithm?
dega512
dega512
It jumps a lot more than 1 pixel. No rounding and it is not just an integer only algorithm. The only part where I really use integers is when I do my fill convention via the ceil function.

Here is an example on how it changes:

No Rotation:


Rotation:
It's easy as 01, 10, 11
Antheus
Antheus
Assuming that's two triangles, then lower left is aligned with lower line, upper right is aligned with upper line.

It looks like problem with perspective correction. You're calculating the texture parallel to uv vectors, without correcting for projection.

If you look at lower left triange, then the bricks are all parallel to each other, when they should be converging to the left.

I'd try searching for some perspective texture mapping (quick google found this: http://www.d6.com/users/checker/misctech.htm), but I'm sure there's plenty others around.

There might also be just a slight bug in the code that causes these artefacts.
dega512
dega512
The code I am using is an attempt at perspective correct texture mapping. The following is what I use to calculate the texture coordinates:


tz1 = 1.0f / z; // tz1 is a temorary value
tz2 = 1.0f / tz1; // tz2 is another temporary value
ut = (u * tz1) * tz2; // ut is transformed u
vt = (v * tz1) * tz2; // vt is transformed v
Texel t = Texture.GetTexel(ut, vt);
It's easy as 01, 10, 11
Sneftel
Sneftel
In your code, tz2=z, and (u * tz1) * tz2 = u.
dega512
dega512
Could I just interlopate U/Z, V/Z, and 1/Z then at each pixel divide my current u and v by my interlopated z?

i.e.

float su = (u1 / z1);
float sv = (v1 / z1);
float sz = (1 / z1);

float ug = ((u2 / z2) - su) / (x2 - x1);
float vg = ((v2 / z2) - sv) / (x2 - x1);
float zg = ((1 / z2) - sz) / (x2 - x1);

while (left to right)
{
float realU = su / sz;
float realV = sv / sz;

// draw texel to screen

su += ug;
sv += vg;
sz += zg;
}
It's easy as 01, 10, 11
noNchaoTic
noNchaoTic
The problem is definately one with your interpolated texture co-ordinates, if you notice, the jumping is occuring across the horizontal line which is dividing the square into 2 triangles. The first triangle looks correct, i.e.: the one on the left, it is my understanding (tho I've not coded this into my software rasterizer yet), that you could interpolate 1/Z across the triangle and divide through by this, but that may not be the case. Looks promising tho :-)
Steven ToveySPUify | Twitter
dega512
dega512
Actually I have now got it working and the problem was in how I was calculating the values to interlopate. What fixed it was the following tip that someone (stonemonkey) gave me:

---------------------------------------------------------------------------

For perspective correct texturing you should be doing the division for each vertex first before the triangle routine,

for each vertex:
tz1=1.0/z
tu=u*tz1
tv=v*tz1

then interpolate those values across the tri and for each pixel you do the reverse

inside scanline:
z=1.0/tz1_interpolated
u=tu_interpolated*z
v=tv_interpolated*z
It's easy as 01, 10, 11

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.