Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Implementing a 2D Distance Field
#1
Pregunta 
I am hoping to use a live camera texture as the basis of a collider. I found a post from 2017 that looks promising:


Quote:- Each frame, render the silhouette of your mesh to a full-screen render texture. White silhouette against a black background.
- Blur the silhouette (using separable linear gaussian blur, if possible). This essentially gives you a sort-of distance field of your humanoid.
- Now the fun part. Use a fullscreen grid-like mesh to create your particles (use a geometry shader to emit a quad per vertex) and read the previous blurred texture at each particles' location. The whiter your texture, the closer you are to the body silhouette. You can use a threshold to control how close your particles are allowed to get to the silhouette. To get a gradient direction (a "normal") to project the particles, just take the derivative of this black/white map.


The first two steps have been achieved, but I'm unsure how to "use a threshold to control how close your particles are allowed to get to the silhouette." Can this be implemented as an extension to the existing ObiColliderBase or ObiDistanceField, or would it have to be an entirely separate set of scripts that modify the position and velocity of each particle? The latter has been advised against in this post:

Quote:You could get particle positions/velocities every frame and implement your own collision detection in C#, but it will be challenging to get it running at an acceptable speed for more than a couple thousand particles.

Any thoughts or examples would be extremely helpful. Thank you!
Reply
#2
(18-06-2019, 05:19 PM)mitch_bi Wrote: I am hoping to use a live camera texture as the basis of a collider. I found a post from 2017 that looks promising:




The first two steps have been achieved, but I'm unsure how to "use a threshold to control how close your particles are allowed to get to the silhouette." Can this be implemented as an extension to the existing ObiColliderBase or ObiDistanceField, or would it have to be an entirely separate set of scripts that modify the position and velocity of each particle? The latter has been advised against in this post:


Any thoughts or examples would be extremely helpful. Thank you!

Hi there,

The threshold part basically means choosing a grayscale value that represents the "surface" of your silhouette, so that any particles in a zone whiter than the threshold value are considered to be "inside" the silhouette (assuming you've drawn a white silhouette on a black background). Darker values for the threshold would keep particles further away from the silhouette.

Regarding collision response, you'd have to implement it as a separate set of scripts that read from your silhouette buffer at each particle's location, and modify its position/velocity.
The advice against implementing your own collision detection should be taken with a grain of salt. First, the cost of getting/setting particle properties has improved a lot since the v3.x times, in 4.x reading/writing particle properties is essentially free in terms of performance. Because of this, performance now entirely depends on how complex your collision response is  (If you do a lot of math for each particle, things will be slower).

Anyway, there's lots of approaches to this. The following is just me thinking out loud:

- Instead of blurring the silhouette, you could use the jump-flooding algorithm to generate a true distance field:
http://citeseerx.ist.psu.edu/viewdoc/dow...1&type=pdf
Looks more complex than it is, can be implemented in few lines of shader code:
https://www.shadertoy.com/view/lsKGDV

- Depending on how precise you want things to be, a valid approach to collision detection with a 2D silhouette would be to first skeletonize it to get approximate bones for the limbs/torso (I think Kinect already does this for you). Then, place a 2D collider at each bone's position/orientation, and use Obi's built-in collision response. Not very accurate (as each limb would be represented by a couple primitive colliders), but gets the job done. If you already have bone info available, I'd give it a try.
Reply