Simulating Chladni Plates in Unity
Fri 28 April 2023 #UselessGameDevThis text is a written version of the video above, with future plans to incorporate graphics and figures for illustration.
As I'm working my way through the backlog of videos that were published before this website, I suggest reading the article alongside the video for a comprehensive experience.
Here’s a situation for ya: you’re walking on a large metal plate that’s covered in sand. All of a sudden, the plate starts to vibrate, and the sand around you arranges in weird eldritch shapes.
If this sounds like a typical Tuesday for you, you might be living on a Chladni Plate. Or in the opening sequence of Rings of Power.
In any case, I’m Leonard and welcome to Useless Game Dev
Chladni Plate
You might have seen Chladni plates in science class, or on your favorite science youtube channels. They are a fun way of visualizing the effects of vibration, and thus sound.
The setup is a simple metal plate connected to a device capable of emitting sound to vibrate the plate. Then covering the surface with sand, the grains of sand will start to rearrange and accumulate, forming patterns that are specific to the sound frequency, and the physical properties of this particular plate.
Standing Wave
Let’s simplify this in a single dimension, using a string. For instance, a guitar string. When stroking the string, a wave will propagate through the string, then bounce back, making the string resonate and thus making sound.
This creates something called a standing wave, where some parts of the string will vibrate a lot, while others will stay completely still.
Now imagine a grain of sand would manage to land on the string, on the part where the vibration is at its peak, called antinodes, the grain of sand would bounce around, back and forth until it settles at a still point, called a node.
The same thing happens with a two-dimensional plate, and sand will pool at the nodes or nodal lines where the vibration is at its minimum.
Enough with the theory stuff, let’s fire up Unity and see if we can simulate this.
Simulation
Rectangular Plate Shader Tests
Before I try to make this using particles, I want to do a quick test in a shader to make sure the concept works.
The most practical formula I found is this one:
a * sin(pi * x * n) * sin(pi * y * m)
+ b * sin(pi * x * m) * sin(pi * y * n)
It looks scary but there isn’t actually much to it:
-
a
andb
are constants that are specific to the plate we’re simulating. The thickness, the kind of metal used, will have an impact on those values. Since we’re in a simulation we’ll pick them at random and see which ones make the prettiest patterns. -
n
andm
are integers representing modes of vibration. There’s some math behind the physics of sound and harmonics that we may want to know about, but ultimately these two numbers are going to define what the patterns look like -
x
andy
are simply the coordinates of the current point on the plate, or in our case, the screen.
So regarding the n
and m
integers, you’ll notice when they are equal, the pattern is a simple grid. There seem to be "families" of patterns depending on the relationship between n and m, and the higher they are, the more lines appear.
Meanwhile the a
and b
values drive the shape and orientation of the lines.
Rectangular Plate Simulation
I have a plate, let’s add sand to it. I’m using Unity’s VFX graph because it runs on the GPU and that’s a good thing when you intend to simulate thousands of grains of sand.
Let’s start with replicating our formula in VFX Graph. Calculating the amplitude of the vibration is basically the same thing as in shader graph. When a grain of sand is in a vibrating area, a random force is applied to it, and the strength of that force is the strength of the vibration of this point.
To my surprise, this is enough for the simulation to work great! First Try!
I’m adding an invisible box that collides with the sand so that they don’t fall off when they reach the edges of the plate, and voilà!
Now there are still two issues with this:
- Collisions. After a while the grains of sand form a very uniform line, where in real life this would not happen, as the grains would collide. But there’s nothing we can do about that in Unity, so, eh.
- Second issue: Shadows. They’re also technically not available in VFX Graph, but I have a trick up my sleeve: spawn a second particle next to each grain of sand, color it black, place it on the ground and stretch it like a shadow. Does this double the number of particles? Yes. Does my tortured GPU spin its fans at full blast trying to record this video? Also yes.
But it’s all worth it when you can get some B-roll.
3D Chladni Clouds
I tried to add a new dimension to the formula to make it 3D. I’m kind of improvising this because I couldn’t find literature on the subject, but my guess is this would work:
- Add a new eigenvalue called
c
- Add a new mode value called
o
- And jumble together sine waves to make it look like the 2D version, but 3D
a * sin(pi * x * n) * sin(pi * z * m) * sin(pi * y * o) +
b * sin(pi * x * m) * sin(pi * z * o) * sin(pi * y * n) +
c * sin(pi * x * o) * sin(pi * z * n) * sin(pi * y * m)
And it worked! The Chladni cloud looks pretty great.
Conclusion
Hey, so this project was super interesting to make, definitely above my level in terms of math but I did manage to scrape together a good proof of concept I think.
Of course you could always skip the math part and simply use a grayscale sprite that shows where the sand should accumulate.
Chladni patterns are very pretty and it’s weird to think things are vibrating around us in such ways while we’re completely oblivious to it.
I tried to imagine how this would fit in a game prototype but it’s too constrained for, say, maze generation, and definitely too resource-intensive for simple visual effects.
If you're interested in this topic, definitely check out the extra content on Patreon!
There also the full source code for this Unity project on the Patreon page.
Have a good one!
Check these out
- Steve Mould's video on Chladni plates
- brusspup's video on Chladni plates
Music Credits
- "Cool Vibes" Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 4.0 License
http://creativecommons.org/licenses/by/4.0/ - "Super Friendly" Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 4.0 License
http://creativecommons.org/licenses/by/4.0/ - "Wholesome " Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 4.0 License
http://creativecommons.org/licenses/by/4.0/ - "Clarion" by Scott Buckley - released under CC-BY 4.0. www.scottbuckley.com.au
- "A002" by Monoreville Music Center