Below is a triangle with its vertices and uv coordinates. These are read from the input model file.

I don't understand why the texture comes in different orientation than the image.

enter image description here enter image description here

here is the method to calculate uv coordinate for the hit point(ray-triangle code from Moller, Trumbore):

     public bool GetIntersection(Vector rayOrigin, Vector rayDirection, ref 
              float hitDistance, out Vector uv)
        uv = null;

        // begin calculating determinant - also used to calculate U parameter
        Vector pvec = rayDirection.Cross(edge2);

        // if determinant is near zero, ray lies in plane of triangle
        float det = edge1.Dot(pvec);

        const float EPSILON = 0.000001f;
        if ((det > -EPSILON) && (det < EPSILON))
            return false;

        float inv_det = 1.0f / det;

        // calculate distance from vertex 0 to ray origin
        Vector tvec = rayOrigin - verts[0];

        // calculate U parameter and test bounds
        float u = tvec.Dot(pvec) * inv_det;
        if ((u < 0.0f) || (u > 1.0f))
            return false;

        // prepare to test V parameter
        Vector qvec = tvec.Cross(edge1);

        // calculate V parameter and test bounds
        float v = rayDirection.Dot(qvec) * inv_det;
        if ((v < 0.0f) || (u + v > 1.0f))
            return false;

        Vector uvHit = uvVectors[0] * u + uvVectors[1] * v + uvVectors[2] * (1 - u - v);
        uv = new Vector(uvHit[0], uvHit[1], 0);

        // calculate t, ray intersects triangle
        hitDistance = edge2.Dot(qvec) * inv_det;

        // only allow intersections in the forward ray direction
        return hitDistance >= 0.0f;

And here is the method in ImageTexture class to convert the hit point uv coordinate:

    public Vector Interpolate(Vector uv)
        float u = uv[0] - (float)Math.Floor(uv[0]);
        float v = uv[1] - (float)Math.Floor(uv[1]);
        u *= bmp.Width - 1;
        v *= bmp.Height - 1;

        Color cuv = bmp.GetPixel((int)u, (int)v);

        return new Vector(cuv.R, cuv.G, cuv.B);

Also how are the uv coordinates that come from the input model are supposed to be calculated? If this is a big mesh(a terrain) with many triangles how is the uv coordinates for each triangle vertex is calculated?



UV or barycentric coordinates represent a point on a triangle as a weighted average of the three vertexes. You can use those coordinates to smoothly interpolate any value over the triangle, like texture coordinates or the normal vector. So think of it like a two-step process. We map the world coordinates of the intersection point to uv coordinates in "triangle space", and then use those to map to another space, in this case "texture space". Your ray hits triangle ABC and you determine the uv coordinates of the intersection point, let's say (0.3, 0.5, 0.2). Intuitively, we're sort of saying the intersection point is 30% A, 50% B, and 20% C. Each vertex would have a texture coordinate, i.e. a pixel in the texture image, associated with it (that's part of modeling / setting up your scene, not something calculated at runtime). Mix the texture coordinates at A, B and C in that ratio and you'll get the point on the texture image associated with that point on the triangle.

This scratchapixel page has some good diagrams and clear explanation.

edit: I'm sorry, I missed the part about how to calculate the coordinates in the first place. The page I linked explains it better than I could anyway.


Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.