Coding Adventure: Atmosphere

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Every time he uploads a video it completely makes my day. It's aspirational to see someone work through everything with such deliberateness while also sharing their mistakes along the way.

👍︎︎ 125 👤︎︎ u/The_Shrub_Patrol 📅︎︎ Aug 22 2020 🗫︎ replies

Seb if you're reading this I love you

👍︎︎ 37 👤︎︎ u/Wacov 📅︎︎ Aug 23 2020 🗫︎ replies

I am subscribing to this guy RIGHT NOW

👍︎︎ 17 👤︎︎ u/theAnalepticAlzabo 📅︎︎ Aug 22 2020 🗫︎ replies

Next Coding Adventure: Spore

👍︎︎ 5 👤︎︎ u/_Yowax_ 📅︎︎ Aug 23 2020 🗫︎ replies

Beaute of a presentation. Love the editiing, presentation, voice. Sub'd.

👍︎︎ 7 👤︎︎ u/ThePostFuturist 📅︎︎ Aug 22 2020 🗫︎ replies

Yep, awsome as always. Although I don't find the green part of the shadow realistic. It looks wrong and that's a shame after all the incredible theory and shaders behind it

👍︎︎ 6 👤︎︎ u/LouisDuret 📅︎︎ Aug 23 2020 🗫︎ replies

Just INSANE

👍︎︎ 2 👤︎︎ u/Equixels 📅︎︎ Aug 23 2020 🗫︎ replies

I love when he makes videos about physically based approaches to real world things, they provide a great reference

👍︎︎ 2 👤︎︎ u/hopefullyidont1 📅︎︎ Aug 23 2020 🗫︎ replies

Wow. Just wow

👍︎︎ 1 👤︎︎ u/gregsolo 📅︎︎ Aug 23 2020 🗫︎ replies
Captions
[Music] hi everyone i've recently been messing about with creating little procedural planets and there's still loads of things that need to be improved but by far the most upsetting thing is how the sky is pitch black even in the middle of the day so to fix that in this video i'm going to be attempting to create some atmosphere my first step is going to be to write a post-processing shader that will be responsible for drawing the atmosphere around our little planets so this here is the fragment program of that shader which will be run for every pixel on the screen so for example if i get the current pixel color and return 1 minus that we'll end up with this that's not terribly helpful though instead i want to draw essentially a bubble so we'll need to figure out where the view from the camera intersects with a sphere around the planet happily i already have this bit of code from the simple ocean shader last video and that'll tell us how far the view ray has to travel to reach the surface of the sphere and also how far it travels through the sphere to complicate matters a bit if we're looking at the planet then the distance through the sphere should be cut short by the planet's surface so let's dive back into the shader and i'll start by getting the origin and direction of the v-ray for the current pixel which we can then give to that ray sphere function to find the distance to and through the atmosphere i have long since lost any faith in the code i write so to quickly check that this is doing what i hope it's doing i'll return the distance through the sphere divided by the sphere's diameter and actually that does look about right we still need to account for the planet surface though so we can sample from the camera's depth texture which will just tell us how far away whatever was drawn to this pixel is we can then correct the distance through the atmosphere like so this is the result now but annoyingly you might notice that the ocean isn't being accounted for which is because it's actually a post-processing effect as well and not included in that depth texture so i'll need to quickly go back yet again and just calculate the distance to the ocean sphere over here and then the distance to the planet's surface is whichever is smallest between the scene depth value and the distance to the ocean just to liven things up a bit i'll multiply the output by the v ray's direction with x y and z being interpreted as red green and blue and that'll give us this groovy result so we've got our little bubble but to make this actually look like an atmosphere is clearly going to take some work i do have some idea how to approach it though because a little while back i experimented with clouds and the basic idea there was to represent the density of water droplets by mixing layers of noise and then approximate how light might be scattered as it travels through that space the scattering of light is also what makes the atmosphere visible so i'll be able to draw on what i learned from these great resources during my research for the clouds but i'm also going to be using accurate atmospheric scattering by sean o'neill as my guide for this project because it looks like a really nice breakdown of how to actually compute these intimidating looking scattering equations so an atmosphere is made up of loads of tiny little molecules like nitrogen and oxygen in the case of earth and these will be quite tightly packed together close to the surface but as we go higher and higher gravity gets weaker and there's less gas pushing down from above and so the little molecules will be spaced further and further apart and at a certain altitude for practical purposes we'll say that's the end of the atmosphere now light from the sun enters the atmosphere and its interactions with the gas molecules cause it to scatter about the type of scattering we have here is called rayleigh scattering which happens when the size of whatever's doing the scattering like how gas molecules is a lot smaller than the wavelength of the light in this case when the light interacts with the molecule it will mostly be scattered forwards and backwards and less so in a perpendicular direction giving us this pleasant peanut pattern happily unless you despise blue skies and sunsets the amount of scattering is dependent on the wavelength of the light with violet light for instance being scattered about 10 times as much as red light intuitively i guess this makes sense if you think how shorter wavelengths will have more opportunities to interact with stuff but i'm not sure if that's how it actually works in the confusing quantum realm of light anyway this is in contrast to me scattering which occurs with things that are roughly the same size or larger than the wavelength of light such as dust particles or water droplets in clouds in this case the light is predominantly scattered forwards and all wavelengths are affected pretty much equally which is why clouds appear grayish-white for example again i guess it makes sense that when the things you're interacting with are big having a shorter wavelength doesn't really help you meet more of them for today though i'm just going to focus on rayleigh scattering so as we saw violet light scatters the most so it'll be coming from pretty much every direction meaning wherever you look it's going to be entering your eyes making the sky that distinctive violet colour we all know and love okay after a little research apparently the sun doesn't produce that much violet light and our eyes are also less sensitive to it so blue predominates green light doesn't scatter as much as blue does and red light even less so so you won't see much of them unless you're looking directly at the sun however if our view is all the way over here then it's an extra long journey through the atmosphere so almost all of the blue light is going to get scattered away before reaching the viewer most of the green light will be scattered away too leaving primarily the red light which will scatter a bit as well giving us a beautiful fiery sunrise or sunset unfortunately if we were to try simulate all these little interactions it would take hours and hours to render a single frame which wouldn't make for the most exhilarating gaming experience so we're going to need to resort to some crude statistical approximations let's get back to the code editor and i'm going to make a little function called calculate light which i'll take in an origin direction and length to describe the view ray of the camera through the atmosphere for the current pixel the only way for that pixel to be illuminated at least in our simplified model is if light travels from the sun and gets scattered into the path of the view ray which i'll refer to as in scattering now this could happen anywhere along the view ray but in order to calculate it we'll need to pick a finite number of points with more obviously being better for quality but worse for speed [Music] so in the code i'll set the first inscatter point to be at the ray origin and then i'll run a loop for the number of points we want and move the point along the view ray by the step size which is just the distance between the points and we can calculate that like so i'll then also make a variable to keep track of the total amount of light scattered in across all these points so now the question is how much light from the sun is actually reaching each of these inscatter points because some of it is going to scatter away before it gets there and the amount that scatters away depends on the average density of the atmosphere along this ray where the light is traveling or as it seems to be called in fancy physics terms the optical depth so in the code let's first figure out the length of the sun ray which we can do using the ray sphere function from earlier then to calculate the optical depth i'll use my favorite programming trick which is calling a function that doesn't exist and worrying about it later [Music] now the proportion of light that makes it all the way to the in scatter point i'll call the transmittance i'm trying to learn the right terminology but i'm not sure if i'm succeeding in any case if we make a little graph like this when the optical depth is zero the transmittance will be one because all the light will make it to its destination but as the optical depth increases more and more light will get scattered away and so we'll see an exponential falloff in the amount of transmitted light the actual function being graphed here is transmittance is equal to e to the power of negative optical depth in the code we can write this using the built-in exponential function which just raises e to the given power so now that we have an idea of how much light will reach the point the next question is how much of that will be scattered towards the camera well one thing this depends on is this angle here and this is where we could use that peanut function from earlier which would make less light scatter at 90 degrees making the sky a bit darker there i'm going to leave it out for now though because the most important factor is the density at the scatter point so in the code i'll just make up a new function to sample density at a single point and then the greater that density the more light will be scattered so we can increase the in scattered light by that multiplied by the transmittance and the step size one more thing we need to take into account is that as this in scattered light travels towards the camera some of it will be scattered away there as well so in the code i'll figure out the optical depth from the in scatter point to the camera and then update the transmissions to account for that this calculation can actually be simplified to just use a single exponential function simply by adding the two values together it amounts to the same thing anyway we can now return the amount of light that makes it all the way to the camera and our function is complete we still have to implement those two functions i pulled from thin air though so let's start with the density at a single point remember that the atmosphere is most dense close to the surface and becomes exponentially less dense the higher up we go so in the code i'll calculate the height above the surface like so and then i'll scale it to be 0 at the surface and one at the outer shell of the atmosphere just to make it easier to work with now we can use that same exponential function from before and i'll multiply the height in there by some density falloff variable so that we can control the shape of this falloff curve like so now it's a little upsetting to me that the density can be above zero past the atmosphere shell so i'm going to do something a little gross and just multiply this by one minus the scaled height this will force the density to be zero at the atmosphere shell so we can use whatever fall of value we like although negative values would be a little weird we can finish off this function by just returning the result and then let's move on to the optical depth function remember this is essentially calculating the average atmospheric density along array so if this here is our ray the way we'll estimate the value is simply by breaking it down into a number of points sampling the density at each of those using the function we just wrote and then adding them together and multiplying by the step size the code for this is not terribly interesting so let's just rush through it quickly we set the sample point to start at the ray origin and calculate the step size and initialize the optical depth to zero next we loop for the number of points we want to calculate the density of the current sample point output to the optical depth multiplied by the step size move the sample point along the rain once the loop is complete return the result with that done we can at last get back to the fragment program from earlier and in here i'll check if we're looking through the atmosphere and if so we'll want to find the first point along the view ray that's inside the atmosphere and then we can call the calculate light function passing in that point along with the ray direction and the distance through the atmosphere i'll then output the original color blended with the light and if we're not looking through the atmosphere then just the original color perhaps one day i'll write a piece of code that runs perfectly the first time but today was not that day i had to go back and fix some syntax errors after which the pink screen was gone but the atmosphere was way too intense no problem i thought that's what the density falloff is for but that just made things weird i was curious about the noisy region behind the planet and so i tried zooming in on it i'm not sure why these patterns occur in the noise but it seems to be caused by the ray sphere function struggling with precision issues when the given point is right on the surface of the sphere so in the code if i have some tiny value and add it to the starting point and subtract it from the ray length then the noise disappears of course this strange cylinder behind my planet is not exactly welcome either and i eventually tracked that down to a little missing minus sign right over here with that fixed we're now left with a little misty ball around the planet i'm excited to play with the settings a bit i want to see what this looks like with a negative density falloff kind of like a force fielder on the planet i guess we can also play with the scale of the atmosphere and then lastly i have a tiny sun which i can rotate around just to see how that affects the lighting this is quite boring without color actually so let's try fix that we need to form our image out of red green and blue so let's get a rough idea of those wavelengths red is around 700 nanometers green maybe about 530 and blue let's say 440. remember also that the amount of scattering is inversely proportional to the fourth power of the wavelength so i have this atmosphere setting script which is responsible for sending settings over to the shader and in here i'll add a variable to store those wavelengths along with a scattering strength variable now we can say that the scattering strength of red light is equal to 1 over the wavelength to the power 4 multiplied by the scattering strength and i'll do the same for green and blue now i don't want these values to be ridiculously small because that's annoying to work with so i'll actually change it from 1 over the wavelength to maybe 400 over the wavelength just something that'll bring the result somewhere not too far from one we can then send that data over to the shader and let's hop over to ourselves to actually do something with it so over here we have our transmittance variable and i'll make this a float3 so it can hold different values for red green and blue light and then i'll multiply the optical depths inside the exponential function by the scattering coefficients if we look at a graph of the transmittance now with the scattering strength set to zero all the light will be transmitted but as the strength increases you can see the different wavelengths separating based on those scattering coefficients we calculated and note that red light is transmitted the most in blue the least so the math seems to jack out the scattering coefficients also of course affect how much light gets scattered in towards the camera so we'll need to multiply over here as well this means the inscatted light variable will need to be a float3 and so the function will need to return a float3 as well i'm also going to make a take in the original color so that we can blend that with the in scattered light here i'm not actually sure how to properly do this so i'm just going to use a crude approach for now which is making some of the original color get scattered away on its path to the camera and just adding the unscattered light on top of that we'll need to quickly go back to the fragment program to just update it to work with this new setup but with that done we're ready for the moment of truth this is a bit underwhelming so i'm going to crank up the scattering strength and hope for the best [Music] okay maybe the angels are overselling it a bit but i do think it looks quite nice i love messing with settings so i'm going to again play with the atmosphere scale that looks kind of weird we'll pretend we didn't see that and i also try changing the density falloff but most enticing are the new wavelength settings so let's try tempering with those [Music] i like this pinkish purple one a lot and you can see around the edge the green sunset turning now into a pale blue let's try something a little more dramatic and really split the color bands apart which gives us this wild looking rainbow atmosphere that's a lot of fun to mess with but i'm going to set these back to some more reasonable values for now and let's have a look at this from some other angles [Music] i'll also zoom out a bit and just for comparison i'll switch the atmosphere off for a moment it suddenly looks so hideous without it ah that's better now some of you might be wondering how the shader is in terms of performance and the short answer is not great the longer answer is that of course it depends on the number of in scattering and optical depth points we choose so let's take a closer look at those with just one in scatter point the result is nonsense two and three are pretty bad as well but after that it seems to converge pretty quickly and this is the same with the number of optical depth points so around 10 for both seems to be reasonable at least for this atmosphere settings even that's a bit slow but thankfully that write-up i showed earlier has a section on optimization and one of the first things described is pre-computing the optical depths for all rays through the atmosphere and storing that in a little 2d texture this takes that entire loop that we are having to run for every in-scatter point and just replaces it with attacks to look up that sped things up immensely with the minor trade-off of completely ruining everything i got it working in the end though and moved on to stars which i completely messed up as well in many different ways [Music] what i ended up with is a bit dubious but i'll improve it later hopefully it's essentially just a mesh of a bunch of circles and i can control their size and number and color and so on and then they're drawn with a little shader which looks up the color of the screen where the star is and based on how bright that is fades the star out this means that during daytime the stars won't be visible but as the sun goes down they'll gradually come out to play [Music] now you might notice some ugly color banding going on in the darker areas of the atmosphere and this is something i was able to combat a bit by using blue noise to jitter the inscatted light by a tiny amount this works pretty well in the game but unfortunately the video capture still suffers from these distressing artifacts nevertheless now that our little atmosphere is in place let's go explore the planet [Music] [Music] so far off in the distance we can spy the planet's cyclops with its purplish atmosphere so let's head over there next to take a closer look [Music] so that's essentially all there is to see for now i think the atmospheres have improved the look of the planet substantially so i'm happy with it as a starting point but i'm also very curious to read through some more recent works on atmospheric rendering because the write-up i've been following dates all the way back to 2005 so i'm sure there's been plenty of new ideas and approaches since then to experiment with i'd also love to add some fluffy little clouds and varying weather conditions to the planets not to mention plants and animals plenty to keep me busy for sure anyway that's all i have for now so i hope you've enjoyed this video and until next time cheers [Music] you
Info
Channel: Sebastian Lague
Views: 697,061
Rating: 4.9876742 out of 5
Keywords:
Id: DxfEbulyFcY
Channel Id: undefined
Length: 22min 0sec (1320 seconds)
Published: Sat Aug 22 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.