top of page
  • Writer's pictureMatt Norris

VDB / SDF basics

Updated: Feb 25, 2020

Hi There,

In this post I'm going to give a very quick example of some cool stuff you can do with VDB's / SDF's. I'm not going to dive too deeply into this topic right now but I may come back and do more of a tutorial post about how VDB / SDF maths works, for now I'll just drop some snippets here which cover the single most common use for SDF's, collision detection.

So here's a quickest of quick summaries of how an SDF works, you can basically feed an SDF any vector position and the SDF will tell whether that position is inside the SDF volume or not, then it can also give you a vector pointing to the closest point on the surface of the SDF. Simple really.

So here's a quick demo of what you can actually do with this knowledge.

Pretty cool right? So what's happening here is that I've converted the sphere to a VDB with an SDF assigned to it.

SDF stands for Signed Distance Field and is a specific form of volume/field which stores at each voxel a vector describing the shortest distance from the voxel position to the 'surface' of the field.

I then animate the grid around to make it intersect with the sphere.

Next I perform a collision check with a point wrangle and retrieve 2 pieces of data from the SDF:

1. I retrieve the SDF scalar value, this does two things, firstly it tells me if the position I asked to check is inside the SDF or not. It also tells me, if my position is inside the SDF, the distance from my given position to the closest point on the surface.

2. I retrieve the volume gradient value of the SDF which gives us a vector pointing to the nearest point on the SDF surface.

Finally I combine these 2 pieces of data to push any points that are inside the SDF back towards the surface, job done.

layout for SDF collision check

All quite simple here, I'll add my VDB settings as well, the key thing for this particular demo is to use 'fill interior', it's worth trying without and seeing what the difference is.

'VDB from polygon' settings
  • So voxel size is the resolution of the volume, no surprises there.

  • 'surface' is the name of the SDF we create, we can call it what ever we want but it's going to be necessary to refer to this later so pick something useful.

  • fill interior does exactly what it says on the tin. For very high res VDBs it can be slow to fill the whole interior so use with caution.

point wrangle

and here's the code:

  1. // VDB collsion check in it's simplest form

  2. vector sdf_dir = volumegradient(1, "surface", v@P);

  3. float sdf_mag = volumesample(1, "surface", v@P);

  4. if(sdf_mag < 0.001){

  5. v@P += normalize(sdf_dir) * abs(sdf_mag);

  6. }

So there we go, collision detection in 5 lines of VEX, not bad and incredibly useful! As an aside if you don't want to push the point back to the surface but instead want to just identify the points that are inside the VDB you can simply export that 'sdf_mag' variable as a float attribute.

Bonus Content

One final thing, by taking this setup and putting it in a solver you can get a tasty collision effect that is really useful for damage/impacts.

using a solver for impact effects

Here's an image of the layout

solver layout

And here's what's going on inside the solver node

inside the solver node

This point wrangle is exactly the same one that we used in the standard, non-solved version. except that by using the solver we are able to accumulate the results and create a track or impact groove.

Alright, that is all.

Good luck and happy colliding!

Eddie approves

and remember......

Don't get mad

get vexed!

5,254 views2 comments

Recent Posts

See All


Alexandra Boden
Alexandra Boden
May 24, 2022

How would I write it so that I could CONTAIN an object within a volume? Rather than push it to the outside of the sphere, like in this example.

Matt Norris
Matt Norris
Dec 02, 2022
Replying to

Hi, Sorry for the late reply, I've been really busy and only just getting some time to update the site! If I understand the question you have the following situation: You have a piece of arbitrary geometry, could be anything. You have a second piece of geometry that acts as a container. You want the 1st piece of geo to stay "contained" within the second. I guess the answer here depends on what you mean by "contained" and what the 2 pieces of geo are doing. For example. let say you have a particle sim, maybe a flocking sim as your 1st piece of geo, you've already run the sim and cached it out, but you want to make sure that none of the particles go outside…

bottom of page