Unity Stylized VFX

BlendAdd and Per-Particle Offset in Unity

Learning VFX, Unity3D 5, Stylized

 

After seeing this GDC talk on the VFX in Diablo III, I wanted to learn how to do something similar.

The lava-effect is based on the winning entry of  Riot’s Art Contest on polycount in the category VFX.

To create the splines for the lava-effect I followed this amazing tutorial on editor friendly splines for Unity and did a few modifications so that they work with animations.

BlendAdd

At first I searched for a way to implement the Blend Mode mentioned in the talk. As it turns out, it is very easy to do and should be one of the default blend modes available in every larger engine.

Per-Particle Offset

After having the blend mode done in a custom Unity shader I went on to search for a way to realize the per-particle UV offset that was also mentioned in the GDC talk. Even though Unity has no way of doing per-particle UV offsets with the default particle system, my goal was, to find a solution that works without 3rd party plugins and using solely the default particles.

This workaroung for this problem is absolutely not the best one and I do not recommend using it for anything else than experimentation!

The only way I came up with, without having access to the Unity engine source code and using only the default particle system, was a simple script and a custom shader.

It uses the Blue and Alpha channel of the initial color to offset along U and V for each particle individually. This on the other hand makes the particle Color over Lifetime and Color by Speed unusable as anything else than values of 1 would change the offsets. To compensate this I created the shader with two additional color parameters. One for a lifetime of 0 and one  for a lifetime of 1 and used the Red channel of the initial color as lifetime input, to have at least a linear transition between a start and end color. The same could be done for Color by Speed which would use the Green channel of the initial color and another two color parameters in the shader.