🌈 Andrew ☄️ on Nostr: Yeah, I get what you mean. Although you might even have a ray cast mesh for physics. ...
Yeah, I get what you mean. Although you might even have a ray cast mesh for physics.
Anyway, the issue with multiple samples is that even a small offset between your rays can result in a large change in distance. Even on a trivial surface like a plane. So even before you get to the outliers part you've got a large potential error. See diagram.
I guess ignoring that, you have a good idea of a threshold based on (i.e. 2x) the distance between parallel input ray start points. You can use that to create bins to be used to find a statistical “mode” distance. Basically you put your rays into bins based on hit distance, with bin size based on the threshold, ie. `Map<Bin, List<Ray>>` where bin is `round(dist / threshold)`, whichever bin has the most rays wins, then average the rays in that bin.
I've also seen similar things solved temporally rather than spatially, by cacheing hits. Record the plane made by the mesh normal and point of the hit, and on subsequent frames if your new ray hits that plane within some threshold distance (distance on the plane) of your old hit point, then return the new point (not updating the plane). If it exceeds the threshold, then ray cast against your scene, and update the cached plane. Adapting the threshold to distances and screen resolution takes a bit of tweaking (consider screen space, as a percent)
Anyway, the issue with multiple samples is that even a small offset between your rays can result in a large change in distance. Even on a trivial surface like a plane. So even before you get to the outliers part you've got a large potential error. See diagram.
I guess ignoring that, you have a good idea of a threshold based on (i.e. 2x) the distance between parallel input ray start points. You can use that to create bins to be used to find a statistical “mode” distance. Basically you put your rays into bins based on hit distance, with bin size based on the threshold, ie. `Map<Bin, List<Ray>>` where bin is `round(dist / threshold)`, whichever bin has the most rays wins, then average the rays in that bin.
I've also seen similar things solved temporally rather than spatially, by cacheing hits. Record the plane made by the mesh normal and point of the hit, and on subsequent frames if your new ray hits that plane within some threshold distance (distance on the plane) of your old hit point, then return the new point (not updating the plane). If it exceeds the threshold, then ray cast against your scene, and update the cached plane. Adapting the threshold to distances and screen resolution takes a bit of tweaking (consider screen space, as a percent)