Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by Aeleck · Jul 08, 2020 at 07:31 PM · normalsboundsintersection

Calculate Bounds Intersection Face Normal

I am trying to calculate the normal of the face of the bounds (axis aligned) that a ray intersects. There are a couple modifications to the normal problem of bounds intersections (ray-box intersection) I have made:

  • Ray direction is guaranteed to be normalized

  • I only need the closest point in front of the ray if any (solved in the IntersectBounds method already)

From this I can find the position of intersection regardless of ray origin and direction.

What I really need is the normal of the face it hit. This isn't a raycasting or mesh lookup problem and is purely algebraic as this is used in a compute shader.

Due to this being on the GPU when normally executed, floating point precision is a factor and I am looking for a reliable way to find the normal without just enumerating each face and checking if it's close enough.

Any help is appreciated; a formula or equation of some kind is ideal here. Thank you!

Example code:

 using UnityEngine;
 
 [RequireComponent(typeof(MeshRenderer))]
 public class BoundsIntersection : MonoBehaviour {
     public Vector3 origin = Vector3.zero;
     public Vector3 direction = Vector3.one;
 
     private void OnDrawGizmos() {
         MeshRenderer rend = GetComponent<MeshRenderer>();
         Bounds b = rend.bounds;
 
         // draw bounds, min, max points
         Gizmos.color = Color.white;
         Gizmos.DrawWireCube(b.center, b.size);
         Gizmos.DrawWireCube(b.min, Vector3.one * 0.05f);
         Gizmos.DrawWireCube(b.max, Vector3.one * 0.05f);
 
         Ray r = new Ray(origin, direction.normalized);
 
         Gizmos.color = Color.red;
         Gizmos.DrawRay(r);
 
         float t = IntersectBounds(r, b);
 
         if (t > 0) {
             Gizmos.color = Color.blue;
             Gizmos.DrawLine(origin, origin + r.direction * t);
             Gizmos.DrawWireSphere(origin + r.direction * t, 0.05f);
         }
     }
 
     float IntersectBounds(Ray ray, Bounds bounds) {
         // points on infinite axis that ray intersects, defined by bounds
         // we need to keep considering the max to make sure the min is correct
         float txmin, txmax, tymin, tymax, tzmin, tzmax;
         // solve divie by 0 issues
         Vector3 invDir = new Vector3(1f / ray.direction.x, 1f / ray.direction.y, 1f / ray.direction.z);
 
         if (invDir.x >= 0) {
             txmin = (bounds.min.x - ray.origin.x) * invDir.x;
             txmax = (bounds.max.x - ray.origin.x) * invDir.x;
         } else {
             txmin = (bounds.max.x - ray.origin.x) * invDir.x;
             txmax = (bounds.min.x - ray.origin.x) * invDir.x;
         }
 
         if (invDir.y >= 0) {
             tymin = (bounds.min.y - ray.origin.y) * invDir.y;
             tymax = (bounds.max.y - ray.origin.y) * invDir.y;
         } else {
             tymin = (bounds.max.y - ray.origin.y) * invDir.y;
             tymax = (bounds.min.y - ray.origin.y) * invDir.y;
         }
 
         if ((txmin > tymax) || (tymin > txmax)) return 0.0f;
         // moves bounds in to leave only a 2d plane to check (x-z plane)
         if (tymin > txmin) txmin = tymin;
         if (tymax < txmax) txmax = tymax;
 
         if (invDir.z >= 0) {
             tzmin = (bounds.min.z - ray.origin.z) * invDir.z;
             tzmax = (bounds.max.z - ray.origin.z) * invDir.z;
         } else {
             tzmin = (bounds.max.z - ray.origin.z) * invDir.z;
             tzmax = (bounds.min.z - ray.origin.z) * invDir.z;
         }
 
         if ((txmin > tzmax) || (tzmin > txmax)) return 0.0f;
         if (tzmin > txmin) txmin = tzmin;
         if (tzmax < txmax) txmax = tzmax;
 
         if (txmin <= 0f) {
             if (txmax <= 0f) return 0f;
             return txmax;
         }
         return txmin;
     }
 }

What it looks like in scene with cube near the ray (ray kept at default 0, 0, 0 origin and 1, 1, 1 direction)

alt text

boundsintersection.png (13.4 kB)
Comment
Add comment · Show 5
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 darksider2000 · Jul 08, 2020 at 08:36 PM 0
Share

Silly question, but have you tried RaycastHit.normal? Does it give you the wrong normal?

avatar image Aeleck darksider2000 · Jul 08, 2020 at 08:41 PM 0
Share

Unfortunately, I am not using Unity raycasting. I have the bounds and a ray on the GPU ins$$anonymous$$d of on the Unity processing threads. I am trying to figure this out using only the bounds $$anonymous$$ and max points and the ray origin and direction since I don't have access to the physic space of the scene, and these are just bounds of meshes ins$$anonymous$$d of their actual physics shapes. I should note that the example is so that it can be visualized but will actually be running in a compute shader on the GPU.

avatar image darksider2000 Aeleck · Jul 08, 2020 at 09:18 PM 0
Share

Okay I see what you mean. I've not tried something like this myself, but I might be able to help with the math.


You could use the mesh's normal array to sort out which normal it is you need.

If your contact point is on a face then a vector between the contact point and the face's normal vector's origin will always be perpendicular to the normal vector of that face, and not to any other. (This gets a little tricky around the edges and when the contact point is close to the normal's origin, but should be okay with floats)

So you could just go through the normals array in the mesh, draw vectors and check angles. You can also compare angles and get the one closest to perpendicular to eli$$anonymous$$ate unlikely results. (If your contact point isn't precisely on the face, or if the geometry is complex enough you could get more than one likely result).

Show more comments

0 Replies

· Add your reply
  • Sort: 

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

130 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image 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

What's the best/easiest way to do something like Bounds.Intersects but accounting for rotation? 1 Answer

Problem with getting colliding objects 3 Answers

Mesh collider not working as expected 2 Answers

Surface Intersection of procedural shapes to find vertex normals? 0 Answers

Check if mesh.bounds intersect a plane 1 Answer


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