HomeDesignCreating the satisfying 'swoosh'...

Creating the satisfying ‘swoosh’ effect in Super Lucky’s Tale

Michael Voeller makes video games, real time visual effects, and tools, and is currently working on retro first-person shooter, Prodeus.

While working on Super Lucky’s Tale, something that I thought was solved in a pretty cool way were the “swooshes.” Swooshes are used for collecting coins, spawning certain enemies, and Lucky’s tail swipe effect.

For this type of effect you want a fire and forget solution and you also want it to be super predictable. It should do the same thing every time and keep a consistent look over its lifetime.

An obvious approach may be to use a trail attached to an object that moved toward a target. There are a few issues that may arise with this approach though. If the target moves, the trail could end up having a funny shape, and it could also be difficult to figure out exactly when the swoosh will arrive at the target, which doesn’t help with timing when to spawn things.

The best solution turned out being a mesh that was a strip of polygons with the beginning and end at 0,0,0 with a trail texture that scrolled across it. A script on the swoosh object informed the shader where the target was and the vertex shader moved the end of the swoosh over to the targets position. The script could also orient the mesh to face the target. This allowed for lots of variation in the shape of the swooshes and also guaranteed that the swoosh would reach the target exactly when it was supposed to and always have the intended shape.

 

 

A swoosh model could be made with all kinds of twisting ribbons and then deformed along a path to make all kinds of fun shapes. The important part of the vertex shader that moves the end of the swoosh is below:

 

// For screen shooshes smoosh the mesh flat on the Y axis
v.vertex.y *= 1.0 - _ScreenSquish;

// Add some random offset on the X and Z zxis for screen swooshes
float2 divergence = _Divergence.xy * saturate( sin ( v.uv.x * UNITY_PI ) );
v.vertex.xz += divergence * _ScreenSquish;

// Find the start position of the swoosh
float3 worldOrigin = mul( unity_ObjectToWorld, float4(0,0,0,1) ).xyz;

// Now figure out the end position relative to the start position
float3 endOffset = _TargetPos - worldOrigin;

// Get the world position of the vertex
float3 worldPos = mul( unity_ObjectToWorld, v.vertex ).xyz;

// Add the end offset to the vertex world position masked byt the uv coordinates
worldPos += endOffset * v.uv.x;

// Transform the world position to screen position
o.vertex = mul(UNITY_MATRIX_VP, float4(worldPos,1));

// Smoosh the swoosh against the screen if it is a screen swoosh
o.vertex.z = lerp( o.vertex.z, o.vertex.w, _ScreenSquish * 0.99 );

 

_ScreenSquish is a float from 0-1 that is passed in from script telling the swoosh if it should be pressed against the screen, like the coin collect swooshes. This keeps is from being occluded by any opaque geometry while still being attached to a point in the world. It still follows a world space position but that position is attached to the screen. _Divergence is a float2 passed in from script that adds some offset the the middle of the swoosh so screen swooshes don’t overlap and follow a bit of a random path. The pixel shader is pretty simple, here’s the basic swoosh texture lookup with a bit of fade out on either end:

 

// texture coords for swoosh texture
float2 swooshUV = saturate( IN.uv * _Tiling.xy + float2( lerp( _Tiling.z, _Tiling.w, _Ramp ), 0 ) );
half4 col = tex2D(_MainTex, swooshUV ) * _Color;

// start and end fade in
half edgeFade = saturate( ( 1.0 - abs( IN.uv.x * 2 - 1 ) ) * (1.0 / _FadeInOut ) );
edgeFade = smoothstep(0,1,edgeFade);

// multiply together
col *= edgeFade;

 

_Ramp is passed in from script to control the swoosh travel progression. _Tiling is set in the material and allows for control of the length of the swoosh and how _Ramp effects the swoosh travel. _FadeInOut is lets you set how mush on the ends of the swoosh to fade out.

A material property block can be used to send the information right to the swoosh renderer without messing with the materials at all like so:

 

MaterialPropertyBlock MPB = new MaterialPropertyBlock ();
Renderer thisRenderer = this.GetComponent ();

if (targetScreen) {
 MPB.SetFloat ("_ScreenSquish", 1.0f);
 MPB.SetVector ("_Divergence", new Vector2 (Random.Range (-screenDivergence, screenDivergence), Random.Range (-screenDivergence, screenDivergence)));
}

MPB.SetFloat("_Ramp", ramp);

thisRenderer.SetPropertyBlock (MPB);

 

Now a swoosh can be spawned anywhere, its script will drive _Ramp over a specified time, you know exactly when it will reach the end and what it will look like along the way.

Even when moving the camera a screen swoosh will always start at its world position and end at the screen position, the shape is always smooth and movement always fluid.

Lucky’s tail swipe uses the same shader with an extra texture overlay to make it look more wispy. The tail swoosh is spawned at Lucky’s position and rotation and then the end position is just updated to be Lucky’s current position.

If Lucky is jumping, the tail swoosh it will follow him in the air while maintaining its smooth shape. It’s a subtle effect but helps tie it to Lucky.

But we’re not done yet. You can get really fancy with a geometry shader by turning each triangle into a little particle. Here one of the swoosh ribbons has the swoosh particle shader on it. This shader turned each triangle into its own quad and gave it some movement over its lifetime. Because this is just a shader you can play the whole effect backwards. And like the regular swooshes, the particle swooshes update their positions when the target moves.

How exactly that all works may be a post for another day though.

Most Popular

LEAVE A REPLY

Please enter your comment!
Please enter your name here

More from Author

How a South Korean intern saved Valve from a Vivendi lawsuit

This weekend marked Half-Life 2's 20th anniversary, and NoClip released a...

Unity signs co-development partnership with 2K Games

Today at Unite 2025, Unity announced a multi-title development partnership with...

Becoming One with Nature Takes Time and a Lot of Yoga says Pauline Jacobs

The increase in overall pollution that the planet has seen during...

Contributing to a Brighter Future by Volunterring For Environmental Societies

The increase in overall pollution that the planet has seen during...

Read Now

How a South Korean intern saved Valve from a Vivendi lawsuit

This weekend marked Half-Life 2's 20th anniversary, and NoClip released a new documentary covering the history of Valve's first-person shooter. And the reason for the game's existence can be owed in part to a Korean-speaking intern who came into the picture during a tumultuous legal battle.In the...

Unity signs co-development partnership with 2K Games

Today at Unite 2025, Unity announced a multi-title development partnership with 2K Games that appears to indicate the company is expanding its external development business with major Unity users.The partnership will kick off with Unity leading the way on a Nintendo Switch 2 port of PGA-licensed golf...

Becoming One with Nature Takes Time and a Lot of Yoga says Pauline Jacobs

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...

Contributing to a Brighter Future by Volunterring For Environmental Societies

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...

Letting Loose and Having Fun in the Rural Villages Along the Seine in France

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...

Exploring the Coral Reefs to Understand How Pollution Has Impacted Aquatic Life

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...

Cultivating an Entire Garden Over the Course of a Year and Growing it to Maturity

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...

Hitchhiking from one Side of the Country to the Other while on a Tight Schedule

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...

What Happens when you Lose Yourself in an Unknown, Foreign Country? Advice and Tips

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...

Take a Deep Dive into the Alternate Lifestyle of Paris, France, with Kelly Laurence

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...

A Photo Book with Andreea Martini Following her Trip from one Side of the US to the Other

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...

Discovering a Different Side of Laura Parks in a Beautiful Place Downtown, San Francisco

The increase in overall pollution that the planet has seen during the past few years has impacted the planet in such a way that it caused a ripple effect to happen in various domains. This is exactly why right now is the moment in which all of...