Shaders

Procedural Star Fields by Ryan Smith

It's tough to make a starry-night sky using textures. You either have to use very large textures to get the resolution you want, or you have to use smaller tiling textures, resulting in obvious repetitive patterns. Some people end up using a combination of both which may get the job done at the expense of precious memory.  

The longer you've been doing game development, the more you'll understand that there are countless ways to achieve a desired result. The only difference is what it costs you. Lets take a look at a way to make stars that wont cost you any texture memory. Instead, this method relies on the raw horse power of the GPU, costing us only pixel shader instructions. 

How it Works

The algorithm can be broken down into a few steps. First, generate a grid of UV Cells. Offset the UVs by -0.5 so that the origin is in the center of the cell. Use the cell to generate a radial gradient with a radius of 0.5. Them using a random vector per cell, offset the radial gradient's position and shrink the radius by double the magnitude of the random vector.

To preview the algorithm in action, left click and hold the button down on the below image, and drag your mouse left and right. You'll see the basic steps of the algorithm animate as you move your mouse further to the right of the image.

 

Below is another shader example, this time with a smaller scale and 8 iterations. Drag left to right to watch the offset happen. You can also enter fullscreen mode by pressing the square bracket button on the bottom left. 


A Small Look at Generating Random Noise

At the heart of pretty much all noise generators is a function that creates pseudo random noise.  The function i'm using in the above examples comes from David Hoskins's awesome Shadertoy example. I use the "hash22" function, where the "22" means that the function takes a 2D value as an input and returns a 2D value. The  below method is how i "look up" random values per UV Cell. There are many different ways to generate random noise, I encourage you to read up on these methods since they're an important step to many procedural effects. 

Making it work in the Unreal Engine

To make the algorithm work in UE4, we need to implement a version of the noise that works in 3D. The above shaders work with 2D, but it's easy to change it to support 3D. All you have to do is provide a 3D coordinate as an input, and make sure you have a 3D cell noise, the rest of the instructions are the same. Thankfully, UE4 has the Vector Noise node, which defaults to the Cell Noise type. 

In Unreal, I apply the shader to a inverted sphere with a radius of 50 units.

Procedural Star function graph. UE4

The above graph can be considered a single iteration. In this post's cover image, i'm using 3 iterations, each one having a different grid scale and brightness. Check out the results below. 

That's pretty much it!  I encourage everyone to figure out different ways to make use of this effect other than stars. Thanks for reading.