Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
4
Question by scarecrow77 · Jan 19, 2013 at 09:29 PM · texturemeshuvvertextriangle

Calculate UV coordinates of 3D point on plane of mesh's triangle

I want to calculate the UV coordinates of a point P that lies on the plane of one of my mesh's triangles (with vertices A, B and C). The problem is P isn't necessarily within the bounds of the 3D triangle. For instance P could be just outside the line from A to B etc. P will however always lie in the same plane as the triangle. I know that on the mesh's texture a point outside of a triangle could correspond to an entirely different place on my mesh but that doesn't matter in this instance. Thank you to all who help me :-)

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
28
Best Answer

Answer by aldonaletto · Jan 20, 2013 at 03:14 AM

Interpolation in a 3D triangle is relatively easy: for any given point inside the triangle, we can find 3 interpolation factors that work as weights - we multiply the values associated to the vertices by their corresponding interpolation factors and add everything together. In the case mentioned in your question, for instance, we could find factors a, b and c for a given point P, and calculate the UV pair at this point as:

 var uv: Vector2 = a * uvA + b * uvB + c * uvC;

where uvA, uvB and uvC are the uv pairs associated to vertices A, B and C.
These interpolation factors are called the barycentric coordinates of the point, and can be calculated according to the drawing below:

alt text

The vertices here are P1, P2 and P3, and the point is F. We can think of F as a 4th vertex that divides the main triangle in 3 smaller ones: the areas of these triangles are proportional to the factors we want - the factor a1 (associated to P1) is given by A1/A, a2 = A2/A, a3 = A3/A.
In order to calculate these areas, we use (guess what?) cross products: the cross product of two vectors has a magnitude equal to twice the area of the triangle formed by the two vectors. For points inside the triangle, we can simply get the magnitude of the cross products - it's twice the actual area, but this makes no difference because we're interested solely in the ratio between areas:

 // calculate vectors from point f to vertices p1, p2 and p3:
 var f1 = p1-f;
 var f2 = p2-f;
 var f3 = p3-f;
 // calculate the areas and factors (order of parameters doesn't matter):
 var a: float = Vector3.Cross(p1-p2, p1-p3).magnitude; // main triangle area a
 var a1: float = Vector3.Cross(f2, f3).magnitude / a; // p1's triangle area / a
 var a2: float = Vector3.Cross(f3, f1).magnitude / a; // p2's triangle area / a 
 var a3: float = Vector3.Cross(f1, f2).magnitude / a; // p3's triangle area / a
 // find the uv corresponding to point f (uv1/uv2/uv3 are associated to p1/p2/p3):
 var uv: Vector2 = uv1 * a1 + uv2 * a2 + uv3 * a3;

Notice that this works only for points inside the triangle - but normally this isn't a limitation, because points outside the triangle in UV space usually are meaningless: they can be in a blank area or inside another triangle with a completely different shape.
Anyway, if you really need to interpolate (extrapolate?) points outside the triangle, a more general approach must be used: the "sign" of each area must be taken into account, which produces correct results for points inside or outside the triangle. In order to calculate the area "signs", we can use (guess what?) dot products - like this:

 // calculate vectors from point f to vertices p1, p2 and p3:
 var f1 = p1-f;
 var f2 = p2-f;
 var f3 = p3-f;
 // calculate the areas (parameters order is essential in this case):
 var va: Vector3 = Vector3.Cross(p1-p2, p1-p3); // main triangle cross product
 var va1: Vector3 = Vector3.Cross(f2, f3); // p1's triangle cross product
 var va2: Vector3 = Vector3.Cross(f3, f1); // p2's triangle cross product
 var va3: Vector3 = Vector3.Cross(f1, f2); // p3's triangle cross product
 var a: float = va.magnitude; // main triangle area
 // calculate barycentric coordinates with sign:
 var a1: float = va1.magnitude/a * Mathf.Sign(Vector3.Dot(va, va1));
 var a2: float = va2.magnitude/a * Mathf.Sign(Vector3.Dot(va, va2));
 var a3: float = va3.magnitude/a * Mathf.Sign(Vector3.Dot(va, va3));
 // find the uv corresponding to point f (uv1/uv2/uv3 are associated to p1/p2/p3):
 var uv: Vector2 = uv1 * a1 + uv2 * a2 + uv3 * a3;

NOTE: Once you have the barycentric coordinates (or interpolation factors), any values associated to the vertices can be interpolated exactly the same way: colors, normals, depth, custom values, whatever. This is extensively used in shaders: the values passed in the output structure from the vertex function to the fragment function are interpolated by the GPU much like above, so that the values each fragment actually receives in its input structure vary according to the fragment position in the triangle.


barycentricinterpolation.png (3.4 kB)
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image scarecrow77 · Jan 23, 2013 at 10:23 PM 0
Share

Thank you Aldo this is exactly what I was looking for :-)

avatar image Julien-Lynge · May 16, 2013 at 01:59 AM 0
Share

Wonderful answer, thanks @aldonaletto!

avatar image Crazydadz · Aug 21, 2015 at 06:14 AM 0
Share

Wow, amazing answer and very well explained. Thank you very much!

avatar image fchen0000 · Nov 15, 2020 at 08:39 AM 0
Share

one correction to your answer: using cross product to get the area of triangle, you could get negative area if F is outside of the triangle which is perfect for extrapolation.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Assigning UV Map to model at runtime 0 Answers

Trouble recalculating 3D mesh's triangles after deleting verts 2 Answers

Same material renders differently on a mesh generated from script and normal cubes. 1 Answer

Ways to texture very large mesh 0 Answers

Rotating texture uv on sphere 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges