A static mesh bends and reacts to nearby objects as its vertices follow Niagara particles. Nguyen Tan Sang shares how he built the VFX.
Nguyen Tan Sang started this as an experiment. He had no particular effect in mind; he wanted to see what he could do with
Niagara’s Dynamic Mesh interface. His idea was to let particles move the vertices of a mesh, so the surface would change shape with them.
Artists can deform a mesh visually with World Position Offset, but putting more complex controls into the material can make it harder to reuse. Sang wanted to handle the movement in Niagara, where he could use the same modules he uses to control particles.
He first considered building the mesh from scratch with math. For more complex shapes, it was easier to start with an existing static mesh. In Niagara, he calls that source BakedMesh and uses its vertex count and section data to initialize a dynamic mesh called DynaMesh.
Next, he spawns one particle for every vertex in the source mesh. The Static Mesh Location module places each particle at its matching vertex. Another module copies the mesh’s tangents, UVs and vertex colors to DynaMesh.
During particle updates, a custom module writes each particle’s position to its corresponding vertex. Move the particles with Niagara, and the mesh moves with them.
The vertices also need to stay connected. Sang uses a separate simulation stage to copy the source mesh’s triangle connections to DynaMesh once. Niagara’s Mesh Renderer then draws the dynamic mesh.
For this test, he uses the global distance field to make particles react to nearby geometry. Their movement deforms the connected surface. The setup can also send particle properties, such as color or velocity, into vertex colors for material effects.
Because the source mesh is a user parameter, Sang can change it at runtime. He also sees the approach as a starting point for effects that tear or break apart a mesh. In his tests with thousands of particles, the effect took around 0.12–0.18 ms.
Want to get more comfortable with 3D math?