How to create stars for skybox using shader graph in Unity

Hello everyone, welcome back.
Today, we will create this starry night effect, using shader graph.


This will be the follow up post of my previous How to create skybox using shader graph in Unity, Check it out! if you haven't already.

I am using unity version 2022.2 but it will work on any Unity LTS versions.

For this one we will need a post processing volume with modules, "Bloom" and "Tone mapping" with mode "ACES" and rest is up to your preference.

With those things out of the way, let's get started.

Creating the sub graph

We can modify our skybox shader graph, but it would become a mess. So to keep things a bit simple and readable let's create a "Sub graph".

Think of sub graph as a method or function of our scripts. We can use them as a node in other shader graphs and it can be used for re-usability of our logic or to keep things simple.

Let's create a sub graph, right click > create > shader graph > sub graph. Call it "StarsSubGraph" and double click to open it.

Sub graph is different from shader graph in a sense that it does not have a master node, instead it will contain output node and the properties of sub graph will act as an input ports.

Let's leave output node alone for a time being and create a Simple Noise node. We want to control the scale, so let's create a float property, call it StarHeight. Give default value of something like 100 just so we can see the preview better. Drag it in and feed it into Scale.

It would be best to have an actual star texture, for real life star constellations, but I was unable to create one myself, I also tried using Voronoi, but it looks too uniform so we will us our noise as our stars.

Take its output and feed it into Power node. What Power node does is, it will just perform mathematical power operation but in this context it will darkens the values which are less than 1.

We want to control the power from inspector so let's create another float property, call it StarPower, give a default of something like 50, drag it in and assign to our Power node.

Then we will take this output and multiply it with a Color. Set mode HDR, give a color and very high intensity, feed that into our Output node.

Select our Output node, in the node settings. give a proper name Stars

It will look something like this.



Calculate the UVs

We must calculate the UVs here, otherwise we will encounter weird stretching on the sides.



The reason is, as illustrated in the image, we are trying to apply the texture on our skybox from the XY plane, and skybox is a spherical surface area, so it will wrapped around it and will get stretchinge from the edges.

In order to fix that, we will tell Unity 2 things.

1st apply the texture from XZ plane. as illustrated below.



2nd don't wrap the texture around the skybox, keep it flat, otherwise we will get that stretching on the horizon.

Based on our theory, we need to calculate the UVs. To do that, we need axes information. We are already calculating axes data in our skybox shader so we will feed that into our sub graph.

In our sub graph, create a Vector3 property, call it NormalizedAxes, drag it in. Take its output and feed it into Split node.

The UVs are essentially Vector2 with X and Y component, we need XZ so we will just take that from the Split node.

Let's create Vector2 node, grab our X and Z. That's our first step complete.

Now we need to tell Unity to not wrap our texture. So we will divide our XZ with our Y. and feed it into UV. It will look something like this.



Make ours stars unique from each other.

Now, our stars will be too uniform in terms of color, in real life they shine in different colors.

So in the sub graph, create a Gradient node. Assign colors of your liking. Select mode fixed. Then to work with the gradient, we need Sample Gradient node.

It has a time, which has a valid range from 0 to 1. If we pass 0 it will take the color from very left of our gradient, if we pass 1, it will take color from the very right, and everything in between.

We want random colors, so let's create a Random range node. It will generate values between 0 and 1, based on the Seed.

Let's take our Simple Noise and pass it into Seed, and its output into Time.

We cannot expose Gradient in shader graph as of now, April 2023. So we cannot access Gradient in the inspector, however I still want to access the intensity, So let's create a float property. Call it StarIntensity, give default value of something like 50. Drag it in, Multiply it with our Sample Gradient, we don't need the color anymore, so delete, and take our gradient multiply into final multiply.



Bring sub graph into skybox shader graph

Back into our Skybox shader graph. Drag our sub graph.

Notice, our created properties have become input ports. So we will create three properties, StarHeight, StartPower and StarIntensity here and feed them in.

We will take Normalize node's output and feed it into NormalizedAxes.

Now if we are creating outer space scene, then we can directly add sub graph's output with our final Add node, but it's not the case here, so we will take its output and multiply it, with our sky part, so with Clamp node. then add it with our final Add node.

Our skybox shader graph will look something like this in the end.



Trouble following along? Check out this video.


Thank you so much for reading.

Comments