 # Intersecting The Atmosphere You can find all the post in this series here:

You can download the Unity package for this tutorial at the bottom of the page.

#### Intersecting the Atmosphere

As discussed before, the only way we can calculate the optical depth of a segment that passes through the atmosphere, is via a numerical integration. This means dividing out interval in smaller segments of length , and calculating the optical depth of each one assuming its density is constant. In the image above, the optical depth of the is calculated with 4 samples, each one only taking into account the density at the centre of the segment itself.

The first step is, obviously, finding the points and . If we operate under the assumption that the objects we are rendering a sphere, Unity will try to render its surface. Each pixel on the screen corresponds to a point on the sphere. In the diagram below, that point is called for origin. In a surface shader, corresponds to the worldPos variable inside the Input structure. This is how far the shader goes; the only piece of information available to us are , the direction which indicates the direction of the view ray, and the atmospheric sphere centred at with radius . The challenge is to calculate and . The fastest way is to use a geometrical approach, reducing the problem to finding the intersection between the atmospheric sphere and the view ray from the camera. First of all, we should notice that , and are all lying on the view ray. This means that we can refer to their position not as a point in 3D space, but as the distance on the view ray from the origin. While is the actual point (represented in the shader as a  float3), will be its distance from the origin (as a float). Both and are two equally valid ways to indicate the same point, and it holds that:  where the overline notation indicates the length of the segment between some arbitrary points and .

For efficiency reasons, in the shader code we will use and , and calculate it from :  We should also notice that the segments and have the same length. What we need now to find the intersection points is to calculate and .

The segment the easiest to calculate. If we look at the diagram above, we can see that is the projection of the vector onto the view ray. Mathematically this projection can be done with the dot product. If you are familiar with shaders you might know the dot product as a measure of how “aligned” two directions are. When it is applied to two vectors and the second one has unitary length, it becomes a projection operator: One should notice that is a 3D vector, not the length of the segment between and .

What we need to calculate next is the length of the segment . This can be calculated using Pythagoras’ theorem on the triangle . In fact, it holds that: which means that: The length of is still unknown. However, it can be calculated by applying once again  Pythagoras’ theorem on the triangle :  We know have all the quantities that we need. To sum it up:     That set of equation contains square roots. They are only defined on non-negative numbers. If , then there is no solution, meaning that the view ray does not intersect the sphere.

We can translate this into the following Cg function:

There is not a single value, but three to return: , and whether or not there is an intersection. The lengths of those two segments are returned using the out keywords, which makes any change the function does on those parameters persistent after its termination.

##### ⭐ Suggested Unity Assets ⭐
Unity is free, but you can upgrade to Unity Pro or Unity Plus subscriptions plans to get more functionality and training resources to power up your projects.

#### Colliding with the Planet

There is an additional issue that we have to take into account. Certain view rays hit the planet, hence their journey through the atmosphere reaches an early termination. One approach could be to revise the derivation presented above.

An easier, yet less efficient approach, is to run rayIntersect twice, and then to adjust the ending point if needed. This translates to the following code:

#### Coming Next…

This post showed how it is possible to find intersections between a sphere and a ray. We will use this in the next post to calculate the entrance and exit points of the view ray with the atmospheric sphere.

You can find all the post in this series here:

Become a Patron!
You can download all the assets necessary to reproduce the volumetric atmospheric scattering presented in this tutorial.

 Feature Standard Premium Volumetric Shader ✅ ✅ Clouds Support ❌ ✅ Day & Night Cycle ❌ ✅ Earth 8K ✅ ✅ Mars 8K ❌ ✅ Venus 8K ❌ ✅ Neptune 2K ❌ ✅ Postprocessing ❌ ✅ Download Standard Premium
##### 💖 Support this blog

This websites exists thanks to the contribution of patrons on Patreon. If you think these posts have either helped or inspired you, please consider supporting this blog. You will be notified when a new tutorial is relesed!

##### 📝 Licensing

You are free to use, adapt and build upon this tutorial for your own projects (even commercially) as long as you credit me.

You are not allowed to redistribute the content of this tutorial on other platforms. Especially the parts that are only available on Patreon.

If the knowledge you have gained had a significant impact on your project, a mention in the credit would be very appreciated. ❤️🧔🏻

1. Philip

Hi Alan, this is a great tutorial series. I am getting a page not found for part 8 and also the cheat sheet, fyi. Not sure if they’re just not done yet, or if the links are broken.

Cheat Sheet: https://www.alanzucconi.com/?p=7766

• Alan Zucconi

Hey!
Unfortunately, I haven’t had the chance to finalise them yet! T_T

2. Max

Hello, Alan. Thank you for a great tutorial.

I’ve got a question about _PlanetCentre variable. Are you setting it with material.SetVector from a C# script? It’s a bit confusing, because you calculated centre and added it to Input struct in a previous chapter. Are you not using that? And if you are, how do you pass a value from Input struct to a lighting function?

• Alan Zucconi

Hey!
Most the properties (such as _PlanetCentre) are properties that I initialise manually directly in the Material inspector!

3. Tamas

Hi Alan!

I’d like to ask in which function does the last snippet go?
I’m new to shader writing and got lost at this part.