Creating stylized clouds with Shader Graph and Shuriken in Unity3D

Mike Young
6 min readMar 14, 2022

--

In this post, I’ll explain how I used URP’s Shader Graph and Unity’s built-in particle system to create these fluffy space clouds.

UPDATE: You can now just purchase the file directly from this link if you’d like to skip all the steps! It’s on sale for pretty cheap right now, I’d say it’s worth it! Click here for the Gumroad link to purchase the shader file.

I combined resources from two helpful assets/tutorials to pull this off:

  • This overview of a similar shader by Roman Papush —I modified some parameters and some node sections to get this to work for 3D cloud-shaped meshes vs. an infinite flat cloud plane.
  • The stylized clouds asset — I used the meshes from this, but you can use any cloud mesh you want and implement the same system I did.

I also implemented a particle system-based cloud generator that you can also use to take your clouds to the next level.

The setup

Spacefreighter (Itch.io link) is a naval combat simulator set in space, where decisions you make about your fleet, weapons, and crew are as important as your skills and tactics in battles. It’s a game about decisions, trade-offs, and making cool ships explode.

In the game, ships sail around in a sky-like form of space and fight each other. Skies have clouds, and we needed ours to feel more like a sky and less like an ocean, so we knew it was time to add some. But clouds are tricky things, especially when they’re this important to our art style. After doing some research, it became clear that the best path was to build our own shader. I wanted to learn more about Shader Graph anyway, so this was a good excuse.

Building the shader

A work in progress pic, applied to a cloud mesh from the Stylized Clouds asset.

First, I created a new unlit shader called MikeCloudShader. Then, I added some meshes to my scene to use as test surfaces. I applied the new shader to a material and assigned it to the sphere. This would let me quickly check on the results of my efforts.

To make the clouds work, I knew I needed to build several “sub-modules” and pipe them all together.

The first group of nodes was the projection group. This basically allowed me to control the rotation of the noise for the shader about an axis — useful. We don’t want patterns with straight lines, because that doesn’t happen in nature. We can achieve some rotation of our projected noise and thus a much more natural look with this block.

I also created some dynamism in my shader by using a time node, scaled with a noise speed variable that I could configure to crank the variation up or down as needed.

The next node group was the noise group. This group used some tiling and offset nodes, coupled with a scaling variable and some gradient noise nodes, to produce a randomized pattern of dark and light — mapped to 0,1 by the saturation node at the end. The waveforms are driven by the output of the time node described above.

By adding two noise nodes together, I was able to produce a pattern that looked like waves of cloud motion moving at angles against each other. This looks much more natural than a single rolling wave traveling all the way around a cloud surface.

I then piped the output of these steps into a series of nodes that set the noise mode. These nodes look complex but basically just allow me to scale the amount of noise further. The remap variables allow for the creation of more contrasting wave height, and the resulting noise has much deeper/sharper valleys, with values ranging from zero on up. Contrast this with a sine wave with smooth troughs below zero — not what I wanted.

I also added a base noise group that is driven from the projection node described earlier. This gives a nice underlying noise pattern that provides some contrast against the bigger peaks from the “main” noise pattern.

Then I added everything together so far and included a base strength scaler. You can see how it all fits together (so far), along with the full list of variables I eventually implemented, in the image below.

I then fed the output of all this into a color and emission node set. This lets me color the clouds and make them glow a bit (I’m using the bloom post-processing effect in my camera stack too). These fed into the base color.

I also need the clouds to be all blobby and undulating. The vertex offset group does this easily. It’s purely offsetting the vertices based on the moving pattern — nothing complex here. These nodes are connected to the position parameter of the vertex part of the shader output.

The result of these steps so far was actually kind of pleasing to watch.

(Applied to a sphere. He is now a blob)

Last, I implemented this somewhat confusing set of nodes to generate some transparency. I connected these up to the alpha channel and enabled alpha transparency on the shader. I basically just copied these from Roman, who copied them from someone else. Vaguely, I know that they allow me to use the scene depth to get how far away the cloud is from the camera and use a density parameter to drive some fog thickness. I wish I knew more about exactly how they worked, although it’s not strictly necessary for me to pull this project off.

Here’s the finished result for the shader

Setting up the particles

The last step was relatively easy — all I had to do was create a particle system that spawned meshes instead of billboards. This can be configured in the renderer module at the bottom of the particle systems settings. And, of course, I saved my shader asset and applied the cloud material to the particles!

I set up two particle systems, one for big clouds and one for smaller “puffs.” the puffs orbit the larger clouds and both cloud types swell and change size as they float around over their lifetimes.

The result

The result is shown below. Note some of our test island assets and the black hole glowing on the left.

The video on the Spacefreighter Youtube channel shows more detail. Note the transparency when the ship is inside a cloud.

The opacity is quite harsh in this video and I’ll probably continue to tweak it to make the clouds feel softer. Overall, though, this gives the stylized look we want.

That’s about it! If you have questions or just want me to share the shader with you directly, join the Spacefreighter Discord. You can also follow along as we build the game and help influence what we build. And of course, I’m happy to answer any questions.

UPDATE: You can now just purchase the file directly from this link if you’d like to skip all the steps! It’s on sale for pretty cheap right now, I’d say it’s worth it! Click here for the Gumroad link to purchase the shader file.

--

--

Mike Young

Writing in-depth beginner tutorials on AI, software development, and startups. Follow me on Twitter @mikeyoung44 !