Skip to main content
gamedev.net
🔒 Locked

Texture Coordinates

Started by CPPNick Dec 30, 2008 at 5:31 PM 8 replies 900+ views
Original Post
CPPNick
CPPNick
Hello. I have my program set up so that my polygon (a triangle) is transformed using a matrix, rasterized, and then put on the screen. while scanning through the pixels in the polygon, how do I find which pixel from the texture goes there? thanks edit: I already know how to go from screen (X,Y) to world(X, Y, Z) using this formula: using 3 points of the triangle, find the plane equation: Ax + By + Cz = D then, let u = x on screen, and v = y on screen z = D / (Au + Bv + C)
swiftcoder
swiftcoder
Typically, one associates texture coordinates with each vertex of the polygon. Then as you rasterise the triangle, you are able to merely linearly interpolate the texture coordinates, and read directly from the texture.

You can also apply a little perspective correction to the interpolation, if you can spare the cycles.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
CPPNick
CPPNick
could you be more specific, or link to tutorial please?
webwraith
webwraith
For a start, you're using u and v as screen x and screen y, directly. Generally speaking, textures are worked out so that each polygon can be "laid" out on the texture and cover a specific part of it. The (u,v) coordinates are then values from 0.0 to 1.0, with 0.0 being bottom/left of texture, and 1.0 being top/right of texture. This allows the computer to keep the size of all coordinates in a texture to a specific size, rather than potentially having a 256x256 texture, where the coordinates could fit in a char, and a 65536x65536 texture, where the coordinates have to be stored in at least a short.

In other words, the u and v refer to coordinates on the texture, rather than the screen, and are fixed to a specific range to keep things uniform.

The remark on linear interpolation is because, as the (u,v) are texture coordinates, its easier to just specify where each vertex in the polygon is, and calculating the texture coordinate at each screen position, dependant on how far the point is between the vertices. As this changes at set intervals (i.e. counting up 1,2,3,etc.), rather than random intervals (1,2,4,5,8,10,etc.), it is linear. Interpolation just means to find the current point given the end points.
swiftcoder
swiftcoder
Quote:
Original post by CPPNick
could you be more specific, or link to tutorial please?
Search for tutorials on texture mapping in software rendering.

Basically, each vertex has a (u, v) pair of texture coordinates, where u is the texture x-axis, and v is the texture y-axis.

So lets say we are rendering a line, with end point texture coordinates of (0, 0) and (1, 0). This indicates that the first vertex is bound to the bottom-left corner of the texture, and the second vertex is bound to the bottom right.

We rasterise the points just like we normally would, but we keep the texture coordinates around. Then for each pixel, we interpolate between the texture coordinates [(0, 0) and (1, 0)], and this tells us the correct pixel in the texture (or texel).
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
CPPNick
CPPNick
here is my problem though...I can understand how that would work in 2D, but I am doing perspective correct mapping.

if I had these points:
bottom_left(0, 2, 5) & bottom_right(50, 20, 10) & top_left(a point that makes the lines joining the three texture coords perpendicular)

and needed to find the pixel for example (20, 30, 35), which is not on either line, how would I do that?

I mean, if it was in 2D, the intersecting lines would already be perpendicular, but in 3d, I need to somehow(and quickly) find a perpendicular line from the point to the line up the Y, and accross the x.....don't I?
swiftcoder
swiftcoder
Quote:
Original post by CPPNick
here is my problem though...I can understand how that would work in 2D, but I am doing perspective correct mapping.
Mot software renderers leave out the perspective correction here, for performance. And honestly, with bilinear texture filtering, you will only notice the difference on huge polygons, than span an appreciable range of Z-values, and since the z-buffer precision is mostly concentrated near the camera, this only tends to happen in the distance, where it is too small to be seen.

If you do feel you need it, you divide (u, v) by z (the depth at the vertex) before interpolation, and then you interpolate 1/z (the reciprocal of the depth) along with (u, v), and lastly divide the interpolated (u, v) by the interpolated 1/z to get the final texture coordinates.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
CPPNick
CPPNick
ok, Im having a hard time understanding, so here is a picture to work with:


I'm thinking that I need to find the magnitude of the blue line, that is a perpendicular line to the one connecting the two red dots.

to find the magnitude of the line, I need to construct a line(in 3d space) from the green point in the middle, that is perpendicular to the line that connects the two red dots. I already have the (x, y, z) of the three points.
CPPNick
CPPNick
Waaaaait a minute...I think I get it. I'm doing the texture coordinates wrong.
It makes sense now that they go at the vertices instead of making the bounding box....

please correct me if I'm wrong:
to find the texture coordinate, I find the distance between the top point of the edge and the point where the scanline intersects it, and divide that by the length of the edge, then multiply the result by the difference between the top texture coord and bottom texture coord.

after having done the above for both edges, I do the same thing, but horizontally to find the texture coords of the point in the middle of the polygon.

does that sound right?

I still don't understand the 1/z thing though...I have read many articles, and even seen source code...but no one gives enough detail about exactly what the variables they are using represent.

thanks again!
swiftcoder
swiftcoder
Quote:
Original post by CPPNick
please correct me if I'm wrong:
to find the texture coordinate, I find the distance between the top point of the edge and the point where the scanline intersects it, and divide that by the length of the edge, then multiply the result by the difference between the top texture coord and bottom texture coord.

after having done the above for both edges, I do the same thing, but horizontally to find the texture coords of the point in the middle of the polygon.

does that sound right?
Yeah, that sounds approximately right.
Quote:
I still don't understand the 1/z thing though...I have read many articles, and even seen source code...but no one gives enough detail about exactly what the variables they are using represent.
z is always depth from your depth buffer, and the 1/z term is only used for perspective correction - ignore it until you have regular texture mapping working.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Topic Locked

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

Sign in to reply to this topic.