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 williamlai3a · Apr 22, 2014 at 09:02 AM · raycastcompute shader

ComputeShader version of Physics.Raycast

Hi all,

I am new on ComputeShader. In my application, I wrote a script that contains many may (>10,000) times of Physics.Raycast However, it is well-known that Physics.Raycast is CPU, and thus slow.

I look into google, and found that ComputeShader Unity is something similar to CUDA And I would like to write a ComputeShader version of Physics.Raycast.

I will be glad if any friends here can give me advise or reference about this. Thanks a lot! and have a nice day.

William

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

4 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by mysteryDate · Mar 11, 2015 at 06:03 PM

This is super possible. It's actually something I have done, it is NOT easy, however. I would greatly recommend this blog:

http://scrawkblog.com/2014/06/24/directcompute-tutorial-for-unity-introduction/

And this post:

http://kylehalladay.com/blog/tutorial/2014/06/27/Compute-Shaders-Are-Nifty.html

Unfortunately, compute shaders are a relatively new technique and resources can be hard to come by.

As far as compute shaders speeding up your raycast, the answer, of course, is "it depends." From what you describe you have many rays, and hopefully few objects in your scene. So you'll likely want to parallelize by having a single thread per ray. GPUs are capable of many, many threads, but as @Benproductions1 said, they're not actually faster (and are infact quite a bit slower) than CPU threads. So if each thread has to look for an intersection with 1000s of objects, it's still going to be slow. One way that Unity (along with other engines) gets around this problem on the CPU is through octree culling:

http://en.wikipedia.org/wiki/Octree

...but I'm getting ahead of myself. Assuming that you don't have too many objects in your scene, here's a simple raycast compute shader:

 struct Ray
 {
     float3 position;
     float3 direction;
 };
 StructuredBuffer<Ray> rays;

 // Three vertices define a triangle in space
 float3 vertA;
 float3 vertB;
 float3 vertC;

 [numthreads(32,1,1)]
 // a 32 by 1 thread group, generally you want to fill up thread groups 
 // which are either 32 or 64 threads wide, GPU dependent
 void RayCast (uint3 id : SV_DispatchThreadID)
 {
     // Our Ray
     float3 pos = rays[id.x].position;
     float3 dir = rays[id.x].direction;
 
     // The normal vector of the plane defined by the triangle
     float3 norm = normalize(cross(vertB - vertA, vertC - vertA));

     // The distance of the ray to an intersection with the plane
     // This is in units relative to the length of ray.direction
     float k = dot(vertA - pos, norm) / dot(dir, norm); 
     // The point in space were the ray intersects the (infinite) plane
     float3 I = pos+ k*dir; 
     // Convert to barycentric coordinates
     // This will find if the intersection is actually within the triangle
     float triangleArea = dot(norm, cross(vertB - vertA,vertC - vertA));
     float areaIBC = dot(norm, cross(vertB - I, vertC - I));
     float baryA = areaIBC / triangleArea;
     float areaICA = dot(norm, cross(vertC - I, vertA - I));
     float baryB = areaICA / triangleArea;
     float baryC = 1 - baryA - baryB;    
     
     if(baryA > 0 && baryB > 0 && baryC > 0 && k >= 0) {
         // The ray intersects this triangle
     }
 }

This would have to run for EVERY triangle that the ray potentially intersects, either with a two-dimensional compute shader (num rays x num triangles), or a for loop within the compute shader. Either way, you're looking at some serious computations.

Now, this doesn't get you 100% of the way there. You have to figure out what the hell you're going to return, and for that you're going to run into race conditions. Yup, there's gonna be some race conditions, good luck!

Comment
Add comment · 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
0

Answer by Benproductions1 · Apr 22, 2014 at 11:20 AM

Physics.Raycast is CPU, and thus slow

Just to be clear, a GPU is not fast, it's merely concurrent. Think of a GPU as having about 32, very old (ie. slow), very small CPUs. Unless you're doing something like 1k+ (arbitrary) raycasts per frame, using the GPU will probably be slower.

Before you ask about how you can implement Physics.Raycast on the GPU, you'd be better of re-implementing it in a normal script first, just so you can understand the amount of work behind it.

To gain any sort of speed boost, you will quite literally have to rebuild a large section of Unity's physics engine, PhysX, on the GPU. This includes spacial trees and the like. You don't have access to any physics or other such API functions from any type of shader, so unless you're either ready to rebuild the PhysX collision system or willing to settle for a horridly slow GPU implementation, I suggest you stick with what you currently have.

Comment
Add comment · 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
0

Answer by williamlai3a · Apr 22, 2014 at 01:42 PM

Thank you for your answer. That's a horrible news.

And as I mentioned, I have to perform more than 10K raycasting (probably increasing to obtain a better result in my application), and that is from each light source that I have on scene.

And of course I understand that single GPU vs single CPU is not necessarily faster. What I understand is exactly about the parallelism, since each raycast does not differ from each other but the initial shooting direction.

So how may I improve this if I do not have the help from computeShader? Any advise? Thanks.

Comment
Add comment · 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
0

Answer by Roni92 · Aug 20, 2015 at 10:27 AM

Hello, how can I call this RayCast method with appropriate arguments, and how to retrieve bool if raycast hitted its target?

Comment
Add comment · 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

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

24 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

Related Questions

How to instantiate gameobject on raycast collision. 1 Answer

Raycast Destroy(hit.collider.gameObject); (Still need help) 1 Answer

Why this script is not working? 1 Answer

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

How To Invoke RayCastAll? 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