Using The Geometry Shader To Implement Model Explosion Effect

0x00 Description

This article will show you how to use the geometry shader to turn the Stanford Armadillo model into sand.

0x01 Implementation

What you may be more familiar with is the “Stanford Bunny”.

They came from models used by Greg Turk and Marc Levoy at Stanford. But the Bunny is so cute, therefore the Armadillo, which looks like a monster, is a good choice. What’s more it has more vertices, so using it for sanding is better.

As you can see, it has 106,289 vertices and 212,574 polygons.

Ok, now let’s import the Stanford Armadillo obj file into Unity and you can see that this monster is already in our scene. Next we will use the geometry shader to implement the desired explosion visual effect.

When I mentioned the geometry shader, I used it to generate more new vertices and polygons to implement the desired effect, such as using it to generate grass on the GPU for real-time rendering of real grass.

But the geometry shader can not only generate new primitives, but it also can reduce the output of vertices and polygons to implement some interesting effects, such as the example in this small article, using the geometry shader to implement the monster’s explosion and sanding effect.

And what we have to do is very simple, that is to change the input triangle composed of 3 vertices into a point composed of only one vertex in the geometry shader.

float3 tempPos = (IN[0].vertex + IN[1].vertex + IN[2].vertex) / 3;
o.vertex = UnityObjectToClipPos(tempPos);

In this way, the mesh that makes up the monster is changed from triangles to points, and the number of vertices is also reduced. As for the monster itself, it becomes like this:

But the model at this time is static, therefore there is no effect of explosion. So next we have to let the monster’s model move over time. And a kinematic formula that everyone knows can be used to implement this effect:

The S is the latest position of the vertex, the values of v0 and a can be passed to the shader as a uniform variable, the direction of motion can be along the normal direction of the triangle, and the value of t is the y component of _Time which is a Unity built-in variable.

Now, we have the variables we need:

float _Speed;
float _AccelerationValue;
float _StartTime

float3 v1 = IN[1].vertex - IN[0].vertex;
float3 v2 = IN[2].vertex - IN[0].vertex;
float3 norm = normalize(cross(v1, v2));
float realTime = _Time.y - _StartTime;

Then we just bring them in the kinematics formula:

tempPos += norm * (_Speed * realTime + .5 * _AccelerationValue * pow(realTime, 2));

The final result will look like this:

And you can find the demo here: Explosion and sand effect

check it out!

Thanks for reading and I hope it’s useful!

Subscribe To Jiadong Chen's Blog

Jiadong Chen
Cloud Architect/Senior Developer

Cloud Architect at Company-X | Microsoft MVP, MCT | Azure Certified Solutions Architect & Cybersecurity Architect Expert | Member of .NET Foundation | Packt Author ㅣ Opinions = my own.

comments powered by Disqus