Geek Culture
Published in

Geek Culture

Smokey Screen Wipe Transitions In Vue

My first foray into the magical and confusing world of shaders

The smoke effect in question

I came across a website that compiled a list of sites with incredible transitions: Smoke Transitions: Beginning of a Trend? I obviously had to figure out how it’s done. The goal? Any kind of screen wipe that resembles billowing smoke would be pretty good.

Demo and Source Code

Use my work as a starting point. Copy the code and play around with it. No amount of write-up from an amateur like me can teach the understanding needed for shaders!

Check out the demo here.

Check out the source code for it here.

Primer

I’ll quickly elaborate on a few things that I didn’t know before this project (to the extent that I understand them) as it is prerequisite knowledge for the end result.

Three.js is a 3D graphics rendering library for the web in JavaScript. 3D rendering requires positioning objects, lighting, and a camera.

3D objects have shaders that define either the positions of their vertices (vertex shaders) or the color of their pixels (fragment shaders). From this point on, I’ll only be talking about fragment shaders.

Shaders are chunks of code that run on each pixel being processed for output. They accept parameters from the outside: uniforms (which do not vary by pixel position) or varying (which do vary by pixel position). Shaders cannot know the output of any other pixel — this is by design, since it means that they are optimized to run in parallel by hardware with many cores (e.g. GPUs).

We need some randomness to simulate the chaotic way that smoke billows out, but also display such randomness in a smooth way (as smoke intensity doesn’t tend to have sharp changes). Fortunately, noise functions fulfill both requirements, though I am not at all qualified enough to describe how they work.

For a tutorial on custom Vue transitions using JavaScript, see my previous write-up.

The Ingredients

The combined result is the result of multiple things working together:

  • A custom JavaScript transition in src/transitions/smoke.js that creates a <canvas /> at the beginning of the exit animation, which is deleted at the end of the animation. The <canvas /> is attached to the parent and has styling that lets it cover up the content being transitioned out.
  • A Three.js renderer that renders a scene on the <canvas />. The scene has a single plane sized and positioned in a way that its texture covers the entire <canvas />.
  • A shader on the Three.js plane that use a noise function and a moving gradient, which combined creates a passable depiction of billowing smoke.

The Shader

Just saying that the shader is responsible for the effect is like saying that a computer is displaying this write-up by reading HTML, so let’s dive into much more detail! The cloud shader is in /src/transitions/shaders/cloud.frag.

At its base, the shader only has three parts:

  1. The part of the screen that has been wiped over, newUv.x / xScale > uThreshold, which has full opacity.
  2. The part of the screen that has not been wiped over yet (the else statement), which is fully transparent.
  3. The part that is being wiped over, newUv.x / xScale > uThreshold - uGradientSize, mathematically calculated as a gradient.

The base moves along the screen to animate a simple screen wipe based on the uThresholduniform passed in, which itself is a function of time elapsed. The effect looks like this:

To add the “billowing” effect, for each pixel in the gradient, we add the output of a noise function to the pixel coordinates, and the pixel returns the color of the base at those new coordinates, which looks like this:

The benefit of a noise function is that the size of this offsetting effect is about the same for adjacent pixels, so the colors sampled are still relatively close together and we avoid large shifts in color. (Honestly, it’s some kind of mathematical sorcery to me). Do this over and over alongside moving the gradient and we have smoke!

Conclusion

I hope that this can help front end devs like me with an intense curiosity unravel the basic mechanisms behind some of the most interesting effects on the web. Shaders open up possibilities that make everything else look primitive. Utilize them and impress!

Like I said, this is my first dive into shaders. I would never have figured this out without being nudged in the right direction, so I have to acknowledge the brilliant people whose work I built off of. I used the cloud effect from this write-up as a basis, then I reverse engineered the wispy edges and generated the gradient for the smoke wipe.

--

--

--

A new tech publication by Start it up (https://medium.com/swlh).

Recommended from Medium

Latest Web Development and JavaScript Trends to Follow in 2022

Daily Dose of Programming Jokes

1035. Uncrossed Lines

Learn TypeScript — The Ultimate Beginners Guide : Generics

Yes, it’s npx, not npm — the difference explained

Vanilla (JS) Slice, Splice, Baby

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Weiming Wu

Weiming Wu

I learn UI skills that my employer doesn't care about

More from Medium

Vue VS React- Best Framework choice for 2022

Tailwind CSS

Adding a Chart to Your Website With Chart.js

How to validate a custom form component in Vue 3?