Wobbling Stuff With Maths – Part 1

This is the start of a series of blogs I intend to write about a fun little side project of mine. I’m kind of making this up as I go along so you’ll have to forgive any obvious mistakes! To understand this you’ll need a basic knowledge of what a mesh is, what vertices are, as well as some intermediate maths, although I’ll try to explain all the necessary stuff as I go along. For the mean time I’ve stripped out all the shader jargon in my code snippets so the maths is easier to read. (N.B. Please add comments if anything doesn’t make any sense and I’ll amend the blog)

Initial experiments

Earlier this year while I was working on my first commercially released game ElemenTales I was asked to write something that’d make some clouds wobble about a bit. To achieve this kind of effect it’s best to use a shader program to directly change positions of vertices very quickly. I took an existing shader that took mesh vertices and wobbled them about using sine waves, a fairly standard practice, and fleshed it out a bit to add some more options. Because it’s all about custom wobbles.

To start with, the original shader program was only operating in one dimension to effectively bob individual mesh vertices up and down over time. This was great and everything but I figured why not allow the program to work in all three dimensions? My first amendment to the shader looked like this:

x = x + xAmplitude * sin(x * time);
y = y + yAmplitude * sin(y * time);
z = z + zAmplitude *  sin(z * time);

Where (x,y,z) are spatial coordinates of a given mesh vertex, the amplitude values adjust the intensity of the effect. So we’re just oscillating the position values over time using a sine wave. Super simple, right?  What I didn’t realise was how cool it’d be to try this on arbitrary geometry with a few tweakable values. For example, this is just a sphere using uniform deformations along the x,y and z axes.

As soon as I managed to do this, I was hooked. This then became a side project with no particular purpose other than to make some cool patterns happen with maths. Since then I’ve added a lot more features.

Extension to use other coordinate systems

The above code will move points about in Cartesian space, i.e. up, down, left and right. To extend this idea further, I decided to try and use some other standard coordinate systems to see what effects they’d have on weird geometries. Remembering back to my maths courses at uni, I figured why not use spherical and cylindrical coordinate systems to modulate things that aren’t spheres or cylinders. Should be fun, right? Maths is always fun.

What all this actually means is that we have three different modulation modes to play with:

  • Cartesian modulation – Oscillate positions up/down, left/right and forwards/backwards as if it were a point on a cuboid
  • Cylidrical modulation – Oscillate the radius, longitude and height of a vertex as if it were a point on cylinder
  • Spherical modulation – Oscillate the radius, elevation and longitude of a vertex as if it were a point on a sphere

Cylindrical Maths

Cylindrical coordinates. (“Coord system CY 1” by Jorge Stolfi – Own work. Licensed under Public Domain via Wikimedia Commons – https://commons.wikimedia.org/wiki/File:Coord_system_CY_1.svg#/media/File:Coord_system_CY_1.svg)

Modulations in cylindrical space are handled similarly to above using the following alternate equations to set mesh vertex positions:

float rho = sqrt(pow(x,2) + pow(z,2));
float phi;

if(x == 0 && z == 0)
phi = 0;
else if(x >= 0)
phi = asin(z/rho);
else if(x < 0)
phi = -asin(z/rho) + PI;

x = x + _CylRadius * cos(phi * time) ;
z = z + _CylRadius * sin(phi * time);

Spherical Maths

Spherical polar coordinates.

float r = sqrt(pow(x,2) + pow(y,2) + pow(z,2));
float theta = acos(y/r);
float phi = atan(z/x);

x = x + _SphereRadius * sin(theta * time) * cos(phi * time) ;
z = z + _SphereRadius * sin(theta * time) * sin(phi * time) ;
y = y + _SphereRadius * cos(theta * time);

So we’ve done all the maths. Where’s the good bit?

And now the fun part. To actually make all of this useful we need to access these modifiers in Unity. Next I added some toggles and stuff so I can switch between various modes or combine modes for extra mathematical madness. This is all done through shader properties viewable in the material inspector in Unity, which I’ll go into in more detail in the next post.

Mmmm delicious options
Material inspector for the vertex deformation shader in Unity

Some cool results:

This is a prototype of a polygonal sea that I made for ElemenTales. Used a large mesh with lots of weird interesting peaks and troughs as a starting point. I was pretty pleased with the results but we never ended up using it for the game.

Combining different modulation types (cylindrical and spherical in this case) can produce some really interesting and completely unpredicatable results! Accidentally made a sort of spaceship thing

A cute little swimming cube I made by applying spherical deformations

This cool jet engine effect was created by nesting several distorted toroids by increasing amounts. Quite pleased with it!

What next?

All of these results are great and everything but they lack restraints to make them stable. The reason all of those clips are vines is largely because they’re completely unstable over any period of time. Obviously this isn’t ideal if you want to use them for anything practical. The next article will go into how I tamed the mathematical beast and turned this shader into something far more useful!

Advertisements

One thought on “Wobbling Stuff With Maths – Part 1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s