Most efficient RayCast length?

Hello, devs! What is the most efficient length of a RayCast? For context, I wrote a script that simulates bullet drop by using raycasts and I was wondering what magnitude(if any) is most efficient for firing rays rapidly. I’ve read that the less distance a ray travels, the less processing power it takes, but in this scenario, it will have to cast more rays. Does it even make a difference considering the distance/amount ratio? I’d figure i’d ask here before doing any testing.

Thanks in advance!

2 Likes

Just searching up on google, I found this.
image

Not sure how accurate it is, so I am going to link some Dev forums to help you.

idont think that have any effect on processing power it cast the ray instantly

2 Likes

Shorter raycasts tend to be more efficient then long raycats.

This does not quite answer my question. To reclarify, a raycast has a distance it travels. If you were to make a loop that fires a raycast at a specific length, and fires another one based on the end position of the previous ray, this loop will create a line of raycasts that just keep stacking. Even though this can be computed almost instantly, it takes up some amount of performance(even if its the littlest) because of how long or short the ray is. so what is the ideal magnitude of a raycast? (yes it needs to be broken into segments because i’m calculating the trajectory of a projectile)

Does it even make a difference?

Oh, shorter raycasts are better I think for what you need.

1 Like

I don’t think there is an efficient raycast length. I’m sure that’s up to you depending on your type of project.

1 Like

I think this is incorrect, when I did benchmarking I found a 2500 stud raycast consistently takes less time then a 5000 stud raycast.
Code:

-- script in serverscriptstorage on default baseplate

task.wait(3)

local StartTime = os.clock()
workspace:Raycast(Vector3.new(), Vector3.new(0, 0, 5000))
print("5000 stud raycast:", os.clock() - StartTime)

local StartTime = os.clock()
workspace:Raycast(Vector3.new(), Vector3.new(0, 0, 2500))
print("2500 stud raycast:", os.clock() - StartTime)

Results:
5000 stud raycast: 0.000017400016076862812
2500 stud raycast: 0.000010699965059757233

1 Like

Raycasts have become incredibly fast over the years. I suggest planning these features into your code to optimize your raycasting:

  • Cache your FilterDescendants table or your RaycastParams. Set it as a local variable and reuse them.

  • Less raycasting the better. The magnitude doesn’t matter unless you’re raycasting a lot. Instead of worrying about the magnitude of these segments I suggest thinking about the number of raycast segments you plan to include. The less the better.

  • You can raycast partially on the client. For example, let’s say you have 5 segments total for the projectile trajectory. The client would raycast all 5 segments. Let’s say on the 2nd-3rd segment the raycast hit something. You could use fancy(ish) math completely on the server to determine where these segments start and end and then you could just raycast between the 2nd and 3rd segment positions and verify if it hit anything. It’s overkill but it would save the server a lot of raycasting. The cons of this is exploiter manipulation which can only happen if you don’t do proper sanity checks and the fact that laggy players may have actually hit something on their screen but the server wouldn’t see it because of their poor and delayed network connection. The second con already happens unless you handle all trajectory on the client (terrible idea) but this would probably extend the gap between pre-existing network delay issues.

Also, it’s worthy to mention that you don’t need to worry about performance until you have a problem. For years I attempted to code everything and anything following performance rules and general writing etiquette and it has destroyed a lot of my projects.

1 Like

Raycasting Length Does Not Matter; Localized Scene Geometry Complexity Does

A lot of people here do not know what they are talking about. And that is fine! This is a very complex topic. Let’s clear up some confusion!

As this is also a fairly complex topic so I’m going to skip over quite a bit of math here – it would be out of scope to explain affine geometry, barycentric coordinates, and linear algebra.

The Complexity of Raycasting: How Many Operations Do We Need?

A scene in computer graphics is made up of lots (usually in the order of millions) of triangles. Triangles are a useful structure from which to construct 3D geometry because they have some nice mathematical properties that make them easy to project, calculate intersections against, or otherwise manipulate.

Specifically, a ray-triangle intersection involves solving a series of linear equations to find a point in barycentric coordinates, then conducting a simple comparison to see if that point actually lies within the triangle.

The following slides are from a computer graphics course taught by Professor Albert Chern at UC San Diego. If you are interested in this stuff, I recommend you take a deeper dive there.

To perform your typical raycasting operation, you need to conduct a ray-triangle intersection against every triangle in the path of the ray.

A naive implementation would be to solve a ray-triangle intersection against every triangle in the scene. This would be very slow; your typical part in Roblox has 12 triangles (2 triangles per face on 6 faces), so if you had 1000+ parts in a scene, you would be performing a large number of operations.

However, we know that a ray has a specific path in the scene. Consider the 2D example below. For most rays, we also know there exist at least a handful of triangles in most cases that will never intersect the ray.

If we come up with some clever scheme to sort the triangles in our scene, then we can skip calculating triangle-ray intersections against triangles we know we will never hit.

And that is what Roblox (as well as most computer graphics applications of raycasting) does!

Spatial Partitioning

Under the hood, Roblox implements some form of Spatial Partitioning to make Raycasting faster.

Spatial partitioning the organization of a geometric scene into smaller “partitions.” The idea is that if we organize our scene into smaller parts in a certain mathematical way, that will give us certain mathematical properties. From those properties, we can easily know which partitions contain our ray, and which partitions do not contain our ray. If a partition does not contain our ray, then it is impossible for a ray-triangle intersection to take place against any triangle in that partition, so we can just ignore those triangles in our calculation.

There are different spatial partitioning algorithms out there that are better in certain cases; BST trees, k-d trees to name a few. We don’t know which type Roblox uses unless they tell us, but the overall idea is the same: Roblox, under the hood, is using spatial partitioning to make raycast operations faster by ignoring triangles the ray will definitely not hit.

Takeaways

Overall, I don’t think you should worry about Raycast length, or raycast performance for that matter. Under the hood, your scene will be partitioned, so most raycasts will be very fast.

If you do care about performance, then the real thing to minimize is not raycast length, but scene triangle count. The more triangles there are in the scene, the more complex the spatial partition will be to traverse under the hood, which will mean longer raycast times.

17 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.