Learning Path of NVIDIA Blast
The intention to learn the blast system came from the games I had played and enjoyed such as Rainbow Six Siege, Rocket League, Splatoon etc. They all have very unique physics behavior, some are realistic and the others are faked. However, all of them utilize the physics behavior to create interesting gameplay. Then I came with a conclusion that playing with physics can create new gameplay mechanism.
I started to research in the topic of physics engine, such as Bullet, Box2D, Havoc and NVIDIA Physx. Then I focused on the NVIDIA library which is open-source and popular among the triple-A game titles. Meanwhile, I did research on the topic of flow, turbulence, destruction and particles, including The Art of Destruction in Rainbow Six: Siege etc.
In addition, I ran the demo sample program of NVIDIA Physx with NVIDIA Visual Debugger. However, as the popular engines like Unreal and Unity have already integrated the NVIDIA Physx into the game engine. Then I started to pivot to NVIDIA Blast which is the latest destruction engine built by NVIDIA . And also I chose Unreal as the platform so that I can gain more experience with Unreal Engine.
To start with NVIDIA Blast, the first thing was to subscribe NVIDIA Developer Program membership to access their GameWorks GitHub repo. As I am using Unreal as the platform, I also subscribed Unreal GitHub membership to access the Blast Unreal integration.
The Blast repo includes core blast library and blast authoring tool to create blast meshes as well as a Unity example. For the Unreal integration, there is no need to download Unreal Engine because the the integration repo can build the right version of Unreal as you build the whole project. Therefore, the first-time build is very time consuming. Then the demo can be run to test the Blast system.
Blast Authoring Tool
Generally, the destruction system is made of two parts, Blast Mesh and Damage Program. The blast mesh that defines a destruction model that is used for the destruction fracturing computing is created with the Blast Authoring Tool. The executable can be found under the folder "blast_tools_and_samples-windows" inside the Blast repo. Here is the link of authoring tool guide. [https://docs.nvidia.com/gameworks/content/gameworkslibrary/blast/1.1/authoring_docs/BlastTool_viewerReference.html]
I created a simple sphere model and exported it as an fbx file that can be read by the authoring tool. This tool can create a hierarchical decomposition of the mesh. The idea of using hierarchical structure and graph to compute the destruction to increase the efficiency of the destruction is covered both on Blast website and Rainbow Six: Siege talk.
For the fracture pattern, this tool can produce generally two types of fracture type, Slicing and Voronoi. Slicing is a very simple way of cutting the object horizontally and vertically. The most naive slicing fracture creates a very regular grid pattern of debris. Added with noise and random offset, the fracture pattern becomes a little bit more organic.
And Voronoi decomposition can create a very realistic destruction pattern with polyhedrons. Here is a video illustrate Voronoi diagram very clearly.[https://www.youtube.com/watch?v=7eCrHAv6sYY]
On Hit Damage
The first type of the damage is triggered by the collision and the result is derived from the Blast Mesh properties defined by the Blast Mesh Component itself. In the BeginPlay() function, the OnHit() function is registered to the OnComponentHit delegate. In the Unreal sample project, we can use ball emitter to test the On-Hit Damage.
The hit damage result is a composition of the impact impulse and the stress solver as well as a damage defined by the Damage Component which I will demonstrate in the next section. Each of those can be switched on or off in the Blast Mesh Component properties. The impact impulse is either a radial damage program or a shear damage program that will be discussed in the next section. And the stress solver, a system encapsulated in the core Blast library, is very useful to get the result of damage by calculating the bending forces inside a Blast Mesh Object. As the stress solver checkbox switched on, even the gravity can break a thin board which is very heavy. And as the impact impulse under the stress solver to be switched, the hit object gets a damage to a number of bonds that take the bending forces.
As a input to the stress solver and impact impulse, the unreal plugin uses this equation to derive the momentum for damage calculation.
m1, m2 are the mass of the destructible object hit bone and the hitting object. v1, v2 are the velocity of the two objects. And the n is the normal vector of the hitting position.
The first part of this formula is the reduced mass. According to the derivation on Wikipedia, it is easy to find out that it is based on an theory that the two objects in the system are only affected by the forces of each other, which follows Newton's Third Law. The pair of forces have the same magnitude and opposite direction. The dot product of the relative velocity and the impact normal, which is the normal of the surface at the hitting point, is a projection of the relative velocity on to the normal direction. The multiplication of the reduced mass and the projected velocity can get the relative momentum in the direction of normal.
Damage Program is how the blast engine defines different types of the damage. Even though the plugin has defined basic damage programs including Radial Damage Program, Shear Damage Program and the Capsule Damage Program. (The following video of Shear Damage Component was implemented by myself, and it is very basic, nothing special. I just did not find them. :P )
Before getting into the different types of damage I would like to illustrate about Base Damage Program which is inherited by all types of damage programs.
The base damage program has a set of event handler functions which will be called before, on and after the destruction happening. And in the -Execute() function which specifies the damage, has a set of input parameters. Taking Radial Damage as an example, it takes the damage amount, local damage position, damage radius and input blast material with Fall Off Damage shader functions. And for the -ExecutePostSplit() function, the Radial Damage Program applies a radial impulse to make the effect to be more explosive.
Triangle Intersection Damage Program
Triangle Intersection Damage Program is supported by NVIDIA Blast, however the interface is not implemented through Unreal Plugin. So I implemented a continuous damage component based on raycasting hit points of current frame and previous frame.
The triangle intersection will break the bonds of a blast mesh that are intersected with a triangle defined by vertices. I used the hit points position and the raycasting start position to create a triangle that could cover all the bonds on the path between the two hit points.
-ApplyDamgeProgram() takes in a transform input of the struct FInput, which contains information of world position and world rotation. Then it will be converted into local coordinates in -Execute() function. So I need to use the position and quaterion to store the raycasting positions and converts it back to positions on destruction.
In other damage programs, the world rotation parsed into the damage program is a rotation from forward vector to the surface normal of the impact point. In my implementation, I used the rotation from forward vector to the ray direction. Then in -Execute() function, I derived the direction in hit object local coordinate backward. I translated the hit position in the ray direction to get a third position for the damage program.
I tried to integrate NVIDIA Blast with NVIDIA Flex as well. Even though I failed eventually, I still would like to show some findings.
Both NVIDIA Blast and NVIDIA Flex has changed Unreal Engine source codes to support their core functionalities, maybe same for other Gameworks Libraries. For example, NVIDIA Blast has modified Skeletal Mesh in Unreal.