Detect the other ending of a complex object as a ray is passed through

Basically, I want to be able to pass a ray through an object. Be it cube, sphere, or triangular prism, like this. Even terrain.

image

(excuse my horrible demonstration)
and get the distance between those two points.

Of course, with one ray, I can get the entering point, and I can pass a ray from that, but I don’t know how to find the end point so easily.

Actually, a broader scope of question is, how would I implement some foolproof soft shadow algorithm (or something along the lines)?

I’m making a renderer currently, and note the little unwanted specks on the side of the mountain on the top right.

You can see ridges in this mountain.

What I’m doing to make shadows is getting the contour hit points and casting them in a direction, and if that shadow ray collides with an object or something, it’d darken the pixel. But I want to do something else.

iirc Soft shadow algorithm requires the intersect point and the "outer"sect point. Which is why I made this thread.

Just a thought I had. You know the thickness of the object from where you hit it on the ray, you could cast another ray on the other side of the object in the direction of your hit point and give it a whitelist of just that object you care about. That should tell you the exit point for an object… of course with terrain you would need to employ some kind of ray marching technique (maybe someone else has a better idea for this.) Or perhaps using the ReadVoxels method on the Terrain object you could find the other side that way, then use a similar ray in the opposite direction technique.

Hopefully that’s helpful.

You could get the part of which it hit (what FindPartOnRay returns first) and add it to a table, then use FindPartOnRayWithIgnoreList using that table.

I’m not certain if this’ll work for Terrain but it should work for BaseParts.

Can’t remember if this is true, but it’s worth testing.

Iirc, a ray that starts inside an object will hit the outer wall.

So, in your example, starting at the light point (offset slightly to be put inside) will hit the dark point.

You can modify my GJK algorithm to return the point of intersection: https://github.com/TylerRHoyer/GJK-3D-Intersection/blob/master/GJK.lua

Mathematically:
You know the entry point by the look of it. If you think about it, for a wedge like that (triangle) you’d just have to find the line and you can easily work out the equation of the line and could probably work off of that to get one of the values.

Now to begin with the issue with an answer by Compiler is that he assumed that you’d have the reflected exit point. A ray however should pass straight through. As such you could use pythagoras in 3D in order to calculate the exit position. This can however be really awkward depending on ray angle and position and a lot of the time your probably going to have to work out one of the co-ordinates (usually the x component but can be the y component) where it decides to leave.

Honestly its hard for me to explain without pen, paper and a diagram :slightly_frowning_face:

First off, thanks for pointing out a potential issue in my thinking. I think I’m misunderstanding what you meant though… let me restate my assumption.

My assumption was that if you extrapolated from your first point of intersect, at a minimum the greatest length from side to side of the object you hit, and used Roblox’s FindPartOnRayWithWhiteList setting its Ray’s start position to the point you’ve extrapolated to in the reverse direction of the initial ray is that you would find exactly the opposite side of the object. I’m not too sure what is incorrect about that assumption. Could you elaborate further?

Thanks again :slight_smile:

Nevermind, it might be an error on my part. Its just the reverse direction bit which slightly confuses me:
https://developer.roblox.com/en-us/api-reference/function/Workspace/FindPartOnRayWithWhitelist

Reading this it hints at being able to white list and ignore assets (when reading ignore list). What would be most probable is to ignore the first instance maybe? The thing is with using the word extrapolated thats assuming the factors are consistent and that a trend would continue. Also would it not return the rays first point of contact as suggested in the documentation in that it returns the point of intersection and the normal (assuming its the line which is at a tangent to the curve / ray which is basically just perpendicular if its a straight line at point x) - but this shouldnt get you the second intersection.

As such for a triangle 3D pythagoras mathematics should probably be applied (and its relatively easy to accomplish to a point). Might be very awkward though.

You can do a reverse RayCast using Model:GetBoundingBox’s max size. The RayCast can whitelist the target part. This way close parts don’t interfere.

Edit: Rereading this it looks like you might be looking for FindPartOnRayWithIgnoreList.

My understanding of the whitelist function is that it will only find points of intercept on the objects in the whitelist.

What I’m suggesting the second ray would have a whitelist with only that one object that the first ray intercepted. It doesn’t really matter if you overshoot the extrapolation with this method, you just want to make sure not to undershoot it. I’ll draw a quick picture of what this would look like:

In this picture the red arrow shows the first ray and the blue one shows the second.

The benefit to doing this, I think, is that it works on complex objects without having to get too fancy. The whitelist portion is important because we don’t care about other objects that might block the ray from hitting the first object. I think this works fine.

What happens if this object was terrain? That’s a huge roadblock because then the ENTIRE terrain is one super complex object. Terrain can have tons of ridges and blockage that can obscure this ray.

For that, see my first comment.