I am working on a software rasterizer for educational purposes and I am having issues with the texturing.
The problem is, only one face of the cube gets correctly textured. The rest are stretched edges:
You can see the running program online here.
I have used cartesian coordinates, and all I do is interpolate the uv values along the scanlines. The general formula I use for interpolating the uv coordinates is pretty much the one I use for the z-buffering interpolation and looks like this (in this case for horizontal scanlines):
u_Slope = (right.u - left.u) / (triangleRight_x - triangleLeft_x);
v_Slope = (right.v - left.v) / (triangleRight_x - triangleLeft_x);
//[...]
new_u = left.u + ((currentX_onScanLine - triangleLeft_x) * u_Slope);
new_v = left.v + ((currentX_onScanLine - triangleLeft_x) * v_Slope);
Then, when I add each point to the pixel buffer, I restore z and uv:
z = (1/z);
uv.u = Math.round(uv.u * z *100);//*100 because my texture is 100x100px
uv.v = Math.round(uv.v * z *100);
Then I turn the u v indexes into one index in order to fetch the correct pixel from the image data (which is a 1 dimensional px array):
var index = texture.width * uv.u + uv.v;
//and the rest is unimportant imagedata[index].RGBA bla bla
The interpolation formula is correct considering the consistency of the texture (including the straight stripes).
I must get some sleep now, but before I get into further dissecting of every single value to see what goes wrong, Can someone more experienced guess why might this be happening, just by looking at the cube?
"I have no idea what I'm doing" (it's my first time implementing a rasterizer). Did I miss an important stage?
Thanks for any insight.
PS: My UV values are as follows:
{ u:0, v:0 },
{ u:0, v:0.5 },
{ u:0.5, v:0.5 },
{ u:0.5, v:0 },
{ u:0, v:0 },
{ u:0, v:0.5 },
{ u:0.5, v:0.5 },
{ u:0.5, v:0 }
[EDIT]
The uv values were to blame, and pixel 50 being in the second zone, as Victor pointed out.
My new uv values:
{u:0, v:0},
{u:0, v:1},
{u:1, v:1},
{u:1, v:0},
{u:1, v:0},
{u:1, v:1},
{u:0, v:1},
{u:0, v:0}
To some extent this was "a bug in my code", but also I had overlooked an important part of the process: the uv values should not just be assigned to the 8 corners of the cube.