• Register
Vertex Shader fun (August 15, 2019)

I really enjoy writing shaders that breathe life into the game world, especially vertex shaders. A vertex shader’s main function is to transform a vertex’s 3d position into a 2d position on the screen for rendering and coloring, but you can manipulate that position in interesting ways to do fun things.

Posted by on

Imgur.com

"I really enjoy writing shaders that breathe life into the game world, especially vertex shaders. A vertex shader’s main function is to transform a vertex’s 3d position into a 2d position on the screen for rendering and coloring, but you can manipulate that position in interesting ways to do fun things.

For cloth, hair, vegetation, or anything that needs to be affected by wind, the vertex shader is the perfect tool. And the code is super small - for my waving flag, the vertex shader is just 3 lines.

//x is length, y is depth, z is Y-height

//horizontal wave - more wavy towards the end

v.vertex.y += _WavingAmount * pow(v.vertex.x, 2) * pow(v.vertex.z, 3) * cnoise(float2(_Time.z * 0.7, v.vertex.z * 2)) * 1 * sin(v.vertex.x * 4 + _Time.z * 2);

//height wave

v.vertex.z += pow(v.vertex.x * 0.4, 3) * 0.6 * cnoise(float2(_Time.z * 0.7, v.vertex.z * 2)) + (pow(v.vertex.x,2) * -0.15);

//more horizontal wave

v.vertex.y += pow((1 - abs(v.vertex.x + 1)), 0.5) * cnoise(float2(_Time.z * 0.5, v.vertex.z)) * _WavingAmount;

Essentially it’s a bunch of sine and noise functions stacked on top of each other to create a natural waving pattern. And a cool thing is that all this can be multiplied by a global float value. Meaning, one number can control the waving amount of ALL objects that are programmed to wave in the wind. Also, all these things run on the GPU, freeing precious CPU resources for important things like AI and physics.

The main reason why I find shader development so fun is that everything can be parameterized and previewed instantly. It’s super easy to expose the waving amount and the sine wave octave values to the material, and turn them into a slider. Then you can go out into the scene and play with those values until you get one that looks just right.

Vertex shaders aren’t good for every kind of animation though... For my main character’s ponytail, I use the built-in cloth component in Unity (which runs on CPU), because it needs collision support. It’s possible to write a vertex shader that reacts to colliders, but it requires some setup and steps that I haven’t investigated yet. On the other hand, the ghost mode long hair runs on the GPU, because it doesn’t collide with anything.

One interesting issue I was running into with vertex shaders is that it doesn’t change depth and normals textures that are used for some post-processing effects (ex: ambient occlusion), even when you add ‘add shadow’ tag in surface shaders… Turns out, there’s a built-in hidden shader in Unity that takes care of depth normals. I had to modify that shader and add the custom render types with the same vertex displacement functions to make sure that the vertices used for depth normals were waving in the same way as the vertices in the normal shader.

Anyway, graphics programming is fun and super useful. Everyone should learn it!" (c) Sean, the Wonhon: A Vengeful Spirit developer.