I reached out to a colleague of mine, Andy, for help with the metaballs shader memory leaks. He came through! In my naivety, I suspected the initialization of the compute buffers to be the source of the memory leak (which, yeah, technically it was), but their lack of disposal was really causing the issue! Newton’s First Law of Energy states that all energy that is created must be destroyed…

In addition to the code above, he added this:

private void OnEnable()
{
    AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload;
    AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
}

I’d never seen this pattern before, nor had I seen OnBeforeAssemblyReload. According to the docs, this event fires both when scripts are reloaded and when entering play mode. Because the metaballs are computed in both the editor and in play mode, I guess the buffer was reinitializing without proper disposal? Yeah, still not entirely sure how the code works to be honest… All I can say is that destroying the buffers those extra times fixed the memory leaks. I tried moving the unsubscription event to OnDestroy(), and the memory leaks returned. That falls in line with Andy said about extra buffers being instantiated specifically when the scene enters play mode, not when it exits play. All in all, I learned that it’s a safe practice to destroy a buffer (conditionally, if it exists) before instantiating a new one.


I’m trying to figure out why my metaballs mesh SDF only gets baked correctly when I go through the SDF Bake Tool and not when running my code in the scene controller. Digging through the MeshToSdfBaker class, I realized that Unity also uses a compute shader to bake SDFs. Something somewhere is getting overwritten. Testing that hypothesis, I moved the metaballs mesh calculation to Update() while leaving the BakeSDF() call in LateUpdate(), but that didn’t work. Then I tried placing BakeSDF() in a million other places—less logic, more brute force, and many, many tests, all with the same result.

My next attempt at figuring this out will be modifying VFX Graph’s MeshToSDFBaker class. The SaveWithComputeBuffer() function gets called when I manually save an SDF with the Bake Tool. That SDF outputs correctly, and I plan to intercept it.


Tags: unity vfx shaders debugging metaballs sdf