Triangle texture coordaintes calculation and other questions

Started by
4 comments, last by leet bix 14 years, 2 months ago
Hey there, I've recently been working on a ray tracer, and I'm wondering about how texture coordinates would work in a few situations. First of all, how do you calculate the texture coordinates of a triangle, a ray, and the point of intersection, how do you calculate the texture coordinates? Also there's a few things I don't understand that I've been wondering about in regards to texture mapping. Given a square texture of, say 128x128 pixels and a triangle, how do you find texture coordinates that map to it? Does it squeeze the whole texture on? Or does it just take a chunk of it? And if so, how do you decide which part of the texture you use? Another thing, in the ray tracer I'm doing, I just implemented bilinear filtering, should I bother with implementing trilinear and mipmapping? Or even Anisotropic filtering? Thank you [EDIT] I also have a question about texturing models. Lets say you have the model loaded along with the textures, how do you know which part of the texture goes where? Particularlly on more complex models where textures look like this: http://www.stromcode.com/wp-content/uploads/2008/03/charactertexture_samgrice.jpg Does the model come with uv information? Or do you have to calculate it? These are all questions I'd love some clarification on.
Advertisement
Texture coordinates are designated by the individual who is modeling. Although to make life easier for modelers there are mathematical means of creating a set of UVs through a calculation this is by no means optimum and the procedure is more often than not implemented manually. UVs are not re-calculated or re-produced or modified during run-time unless there are special circumstances at hand! UVs are shipped as part of the model unless for one reason or another someone decides otherwise.

[edit] model file removed

.x file
 MeshTextureCoords {    72;    0.000000;0.000000;,    0.000000;-1.000000;,


The Coordinates are mapped in two dimensions.... If you are trying to pick ray a point on the texture this is possible... You would have to simply match the point where the pick ray shot through the tri to the corresponding point on the texture.

Let me see ummmm

- pick a vertex of the three subtract it from the other two

- cross product of the two vectors from above for a normal to the surface of the tri; normalize

- view matrix with Eye = Vertice(the one subtracted from the two) At = normal above and Up = the difference between the normals of two vertices texture and world coordinates

- multiply the other two vertices and pick ray coordinate by the matrix

- add the chosen vertices texture coordinates to all vertices and pick ray coordinate

- scale other two vertices into alignment and don't forget to scale the pick ray coordinate too(have fun)

which leaves you with the coordinate for where the pick ray intersected the texture with respect to the intersection with the surface of the tri.....

disclaimer <add something here>

[edit] wow I will never post a model file again /me shakes fist :P

[Edited by - Buttacup on January 24, 2010 5:17:52 AM]
-------------------------------------All my life all I ever wanted to be was, Gangsta!
Vertex coordinates and texture coordinates are two different things.

The calculation method depends on the way you calculate the ray-triangle intersection.

If the coordinates of the vertices, and the coordinates of the intersection points are given:

The way I did it (long ago):

image

First, you make the triangles coordinate system (CS from now) (image, lower-right to upper-left):

x_a = norm(e1);y_a = norm( cross( cross( e1,e2 ),e1 ) );

these are the two axis of the CS_a.
Other parts of the image:
Letters without index (by index I mean _letter), are the coordinates in the world CS.

x_a1, y_a1 are the coordinates of the vertex number 1, in the triangle's CS_a
x_a2, y_a2 are the coordinates of the vertex number 2, in the triangle's CS_a

x_a1 = dot(e1,x_a)y_a1 = dot(e1,y_a) = 0x_a2 = dot(e2,x_a)y_a2 = dot(e2,y_a)m_a = [ x_am=dot(n,x_a); y_am=dot(n,y_a)  ]

transform it to CS b (making triangle right-angled):
m_b = [ x_bm=x_am-(x_a2/y_a2)*y_am; y_bm=y_am ]

transform it, so the perpendicular sides of the triangle become unit length
m_b_mod = [ x_m_mod=x_bm/x_a1; y_m_mod=y_bm/y_a2 ]

So the final formula (lower-left image)
t1 = p1_c-p0_c; // p.._c are the U,V coordinates of the pointst2 = p2_c-p0_c;m_c = p0_c + t1*x_bm + t2*y_bm;

You have to multiply m_c with the sizes of the image to obtain the texel.

Some ray-triangle intersection methods calculate the x_bm, and y_bm values (variable names will be totally different) to check if the intersection point is inside the triangle. So I'm sure there's a simpler way to calculate these. And if you have them, just insert them into the final formula, and you have the texture coordinates of the intersection point.

[Edited by - szecs on January 24, 2010 9:33:54 AM]
For texture filtering.
I'm not sure about min filter (when image is smaller), but max filter (when image is larger) is easy

I use U,V coordinates in texels, so not normalized. (normalized means the image is "mapped" to an unit square.)

See image.
image

nearest filter means you round the u,v coordinates to the nearest integer texel value (pff my terms are a bit iffy).
color(u;v) = fetch_u(floor(u+0.5)); fetch_v(floor(v+0.5));  //floor means rounding down, so that will be the integer part that you can use to access memory// fetch means the memory reading


linear filtering means (AFAIK) the max filter is linearly filtered:
color(u;v) = fetch_u(floor(u))*(1-a)+fetch_u(floor(u)+1)*a; fetch_v(floor(v))*(1-b)+fetch_v(floor(v)+1)*b

bilinear filtering means (AFAIK), that the min and max filters are linear.
trilinear filterind means (AFAIK), that there is mipmapping, but I don't try to explain, because I don't know the terms, I'm not sure how it works and i don't speak English too well.
I made a mistake in my first post. Edited it.

And didn't speak of the result:

It is better to specify the texture coordinates in a way, that 0,0 will mean the lower left corner of the image, and 1,1 will mean the upper right corner of it. So the texture coordinates will be normalized.

I suggest you to look into texture wrapping, I'm sure it's explained much better.

So there may be a situation, when you specify texture coordinates that are larger than 1, or smaller that 0. So the image appear smaller than the triangle. (So you cannot fetch from the memory)

You have to decide what to do.

m_c_u, m_c_v are the normalized texture coordinates of the intersection point (ray) (see my first post)

You can:

a) repeat texture:
m_c_repeat_u = m_c_u - floor(m_c_u)m_c_repeat_v = m_c_v - floor(m_c_v) // bevare! not all languages can handle                                     //floored negative numbers!


b) clamp to a specified color:
if( m_c_u>1 or m_c_u<0 or m_c_v>1 or m_c_v<0)   color = specified_color;else   you can fetch from texture image


d) clamp to edge of texture
if( m_c_u>1 )   m_c_clamp_u = 1if( m_c_u<0 )   m_c_clamp_u = 0if( m_c_v>1 )   m_c_clamp_v = 1if( m_c_v<0 )   m_c_clamp_v = 0


[Edited by - szecs on January 24, 2010 10:29:51 AM]
Thank you very much for the clarification.

This topic is closed to new replies.

Advertisement