Sunday, September 1, 2019

Clouds shader breakdown


 UPDATE: download the project here : https://github.com/AlexStrook/UnlitClouds


 

This is a small breakdown of  the clouds shader I did based on the one from the game "SKY" from thatgamecompany (read more about it THERE)

 The thing that contribute the most to this effect is the mesh itself, and the baked lighting.
I used Houdini + 3ds max to generate that (more info THERE), I'll focus only on the Shader part here, and I used Amplify Shader editor for this

The Shader :





First step of the shader is just to plug the vertex color in emission, to display the previously baked lighting. I use a power with (0.454545) to adjust with 3ds max vertex color (because of all the sRGB/linear/Gamma nonsense)


This effect rely on having a lot of triangles to get a smooth displacement, and Tesselation is great for that if you can afford it. Just check "tesselation" in amplify, and use the distance based mode



Adjusting the Distance value and tesselation factor  to fine tune the performance. For this effect having a very close distance works quite well


Now for the fun part, I add a Noise Generator. It's a handy node that will generate a 3D noise base on a world position. Using 3d noise is the most heavy, you can use simplex too. I'm pretty sure this whole effect could be reproduced with a noise texture and creative UVs.  I added a noise, and in the "Size" input, I add a world position multiplied with a float (this will control the tiling of the noise).
Also a remap from -1/1  to 0/1, to avoid negative values
For noise I'm plugin this in the Debug input of the shader.


Here is what changing the float that control the tiling looks like !


Instead of the using a simple world position, multiplying it with a Vector3 ("NoiseScaleA") allows you to scale the noise non uniformly, very handy ! (it's like scaling your mesh, but you only scaling the input position if that makes sense). I stretched the noise along the Z axis as an example here



Time to add some movement. Pretty straightforward, before I plug my Scaled world position in the noise, i add a vector3 multiplied by time. This allows to control the direction the noise is travelling.


Changing the direction of the noise (This works well because it's a 3d noise, this would be hard to replicate with a 2D noise)


I now plug this in the Local Vertex offset, and multiply with two thing :
A 0-1 ranged float, to fine tune the intensity and a Vector3 (0,1,0), to force my noise to only displace along the world Y axis. You can use the normal of the mesh too if needed, it's justed looked better like this


Adjusting the new paramter, Speed, Size, Strength


For this effect, I decided to duplicate the noise 3 times. Copy all paramter, and add them all together. It reminded me of an old project I did (Cartoon Pyroclastic noise). The idea is simple : For each noise you apply, lower the intensity by half, double the tiling, double the speed. This this idea, then tweak everything !


The relationship between the value of each noise is important, here I tweak only the strength. I find it easy adjust all noise separately (turning all strength but current noise one, to 0), and then adjust the strengths.


 Closer view of how the noise are merged together



For the fading edge a simple setup with Transparent material, and a Depth fade.




This part is more a hack, but it add a lot of details. Basically I add a black and white texture of cloud, using triplanar mapping. To get the triplanar mapping animated I use the modified world position from noise C (See image 01), and I multiply everything with the Noise A to "erase" the texture here and there (See image 02)

Img 01. World pos from Noise C

Img 02. Noise A 
I used Register/Get local variable, to avoid spaghetti connection, it's an amazing feature from amplify editor.


this is how the clouds texture looks like.




You can see the difference the cloud texture make, it's pretty neat !


Thanks for reading, if you have any comments/question, post them here or, on twitter where I'm more active :)



NOTES :



  • This is all baked and static, but I'm sure you could make this a lit shader. You might want to reconstruct the normals from the displacement, you can use those node to do it :

  • I intended to, but didn't have time to add flowmap to this effect. Flowmap would help define the direction of the tiling cloud texture And/Or the noise scrolling
  • Here is another technique i saw a while ago that very interesting LINK TO VIDEO (around 10 min). They made clouds in Battlefield one by carefully positioning billboard. it looks great but i guess they had to do some crazy magic behind the scene to make the overwdraw viable...also idk if you can go through them ! 
  • The way they did the clouds in Sky was using raymarching, mike lester from ThatGameCompany who worked on the game : LINK TO TWEET


1 comment:

  1. nice work! also nice that you share your idea here :)

    ReplyDelete

Pinned

"This year I'll learn Learning Blender" he said for the 5th year in a row. + BforArtists

- What a fool   Context: I have 10+ years of 3DS Max experience, I initially started learning it by myself, then went to 3D school, and spen...