Coding Adventure: Terraforming

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Dude, it's like music, documentary and coding made love and this comes out. Awesome content.

👍︎︎ 88 👤︎︎ u/boltforce 📅︎︎ May 29 2021 🗫︎ replies

I love all of his videos

👍︎︎ 251 👤︎︎ u/QuantumX42 📅︎︎ May 29 2021 🗫︎ replies

Wow, this is great stuff. Superior production quality, concise where it needs to be and just detailed enough to to point you in the direction of further study when necessary. Thanks for posting!

👍︎︎ 45 👤︎︎ u/ShitOnRickard5 📅︎︎ May 29 2021 🗫︎ replies

At first, I thought it was about terraform

👍︎︎ 36 👤︎︎ u/Kitchen_Share_3908 📅︎︎ May 29 2021 🗫︎ replies

I love to relax and eat some snacks while watching coding adventure videos

👍︎︎ 48 👤︎︎ u/CuajadaHacendado 📅︎︎ May 29 2021 🗫︎ replies

Another Sebastian Lague video! I am at a fancy restaurant now, so I’ll chug my food and race home!

👍︎︎ 29 👤︎︎ u/avwie 📅︎︎ May 29 2021 🗫︎ replies

"It's not a bug, it's a mirage"

words to live by

👍︎︎ 30 👤︎︎ u/funciton 📅︎︎ May 29 2021 🗫︎ replies

This is my first time seeing his videos, and they're great. Thanks for sharing!

👍︎︎ 7 👤︎︎ u/rethumme 📅︎︎ May 29 2021 🗫︎ replies

When I compare this to my own coding efforts, I find it terror forming.....

👍︎︎ 3 👤︎︎ u/TheDevilsAdvokaat 📅︎︎ May 30 2021 🗫︎ replies
Captions
hi everyone welcome to another episode of coding adventures [Music] when making planets in the past i have always taken the approach of starting with a sphere and then sampling a 3d noise function at each point and stretching those points in or out based on that noise value by mixing and layering different noise functions and experimenting with different equations we can get some pretty interesting results but this approach has a limitation each point can only have one height associated with it which of course means no caves or tunnels or overhangs of any kind [Music] this is the approach i went with when i was tinkering with this little outer wilds inspired project and while it's pleasant to take a stroll on a moon made from math it's a little sad knowing there's no possibility of coming across a lava tube to explore for example or digging your own little cave to take sheltering so in this video i want to try create a little planet and a terraforming tool so i can make caves and tunnels and shape the terrain to my heart's content as a starting point i'm going to use an old project of mine where after some difficulty i managed to implement an algorithm called marching cubes [Music] i have a whole video on that but the basic idea goes like this we take eight points at the corners of some imaginary cube and each of these points has a random value associated with it from our noise function values above zero mean that those points are in open space i like to think of them as air points whereas when the value is below zero those are rock points because they're inside the planet between air and rock is where we want to draw the surface mesh of our planet now with eight points there are 256 possible configurations but they're actually only 15 unique cases and the others are just various symmetries of those and as you can see these surfaces are all constructed out of triangles because computers love drawn triangles so to make our planet we'll have a 3d grid of values classified as either air or rock and will match through that space cubed by cube constructing the surface mesh for each one as we go along [Music] this marching cube's algorithm was published all the way back in 1987 with the purpose of visualizing results from medical scans but it's perfect for games as well i'll show the code for this quickly for anyone who might be curious so the bulk of it is actually just a giant table describing how to connect the triangles for each of those 256 configurations i mentioned and i'm forever grateful i didn't have to figure these out myself because there are a lot of numbers the core of the algorithm though i wrote in something called hlsl and that allows a lot of cubes to be processed in parallel on the gpu over here we start by calculating the coordinates of the eight corners of the current cube and then here we look up each of their values and use that to determine which of the 256 configurations this cube is in then from that giant table we can find out which edges of the cube the surface is passing through these edges are arranged in groups of three and we need to connect them up to form the triangles so i have these two little arrays which just let us take an edge and look up the two points at either end of it so we do that here for each of our three edges finally we need to decide where along each edge we want to place the vertices and for now i've just put them all at the midpoints so let's make something with this i have written this tiny script that just calculates values for a sphere and stores those in a 3d texture i want to take a quick look at slices of that texture just to make sure it's working properly so these lighter regions are outside the surface everything drawn in black is below the surface and the red line shows the boundary between the two so where the value is zero i thought that was looking good so if i tell the matching cube script to get its data from this texture we should end up with a lovely 3d sphere and here it is it is a very blocky looking sphere though and while blockiness is not necessarily bad i'd like to smooth it out a bit so instead of placing every vertex at the midpoint of an edge let's make a little function called calculate vertex position and what that function will do is look at the value of both points that's been given one will be positive and one will be negative and it'll figure out where along the edge zero should be and that's where the vertex will go that little change takes us from this to this that's looking pretty smooth so i'll quickly return to where we're calculating those sphere values and let's try sprinkling some layers of noise on top like so [Music] here's what our 3d texture looks like now so let's once again use our matching cubes to construct a mesh it looks like we're getting somewhere at last unfortunately with this technique we do occasionally get random rocks floating in the air and while it should be possible to remove them with some sort of flood fill algorithm i suspect it'd be quite slow far more practical is just to wave it away with some nonsense physics so just for fun i thought i'd ask an ai to try offer some explanations for this floating rock phenomenon let's see what it was able to come up with [Music] rocks float in the air because they are not dense enough to remain on the ground there is less gravitational pull on rocks floating in the air because they're at a high altitude and so they tend to hover this phenomenon cannot be explained although some theories suggest that it is a mirage caused by very hot sun rays this is because the magnetic forces inside of the rock repel each other and push the rock up into the air and finally i got hit with some hard facts rocks don't float in the air they are too heavy for that anyway there are clearly plenty of excuses for our rocks to float so let's label that a feature and move on to the more pressing concern that this terrain mesh is already using over a million vertices a lot of those are probably duplicates though because i'm not sure how to share vertices between the cubes since i don't understand all this fancy parallel gpu stuff terribly well if i'm honest but since i anyway need to read the mesh data back to the cpu in order to generate the collision mesh we're now in c-sharp land and so i can simply loop over all the vertices and weed out the duplicates using a dictionary which is surprisingly fast this has the side effect of making the shading smooth which i actually want for this project so that's nice and if i bring up the mesh info again it looks like we've brought the vertex count all the way down to about 180 000 anyway i've now created a simple player controller that works for planets where the direction of gravity obviously depends on where you're standing it's uh got some issues at the moment but i'm working on those now my main goal here is a terraforming ability so you can click to carve out a tunnel for example but it would be pretty inefficient to regenerate the entire planet each time a change is made so i need to split it up into chunks i've been working on the code for that for quite a while now so it's with plenty of anticipation and trepidation that i'm at last ready to try it out well i think it goes without saying that that's not even remotely what i had in mind but it shouldn't be too hard to fix [Music] [Music] that's still not quite right but it looks like we're heading in the right direction it just needs a few tweaks [Music] i'm not sure how but i seem to have turned the planet into some strange sort of fungus i have an idea what might be going wrong [Music] though great now nothing's happening at all oh it looks like it was actually doing something it was busy constructing this interesting monstrosity [Music] [Music] well i guess you could call that an ed griegas display of programming i need to take a break [Music] coming back to this the next day i was thankfully able to track down the problem pretty quickly and get it working at long last my mistake as usual was rather silly but in case anyone cares to know here's what happened on the c-sharp side of things unity provides two types of 3d vectors one for integers and one for floating point numbers i happen to have a vector3 int with some data i wanted to send over to my compute shader so i thought i'll just use this handy set vector function but it complained that it didn't like the type of variable i was giving it and without really thinking i just converted it to a regular vector 3 like this and that made the squiggly red line go away which of course is all i'm really trying to achieve when i'm programming over in the shader i was using the equivalent of a vector 3 inch which there is an intri so here's what was happening first i have some data stored in a vector3 inch and in binary that data looks like this then i cast that to a regular vector3 to get that pesky error to go away and even though it's the same values in there the actual binary data of course looks quite different because it's now in the floating point format but i almost never think about the raw binary data in my day-to-day programming so even though i technically knew that these exact bits would end up in the gpu for my little chunk id variable that didn't trigger any alarms in my head that now when i was expecting a value of 22 for example i would actually get 1 102 53 376 which as you saw resulted in some issues the solution to all of this by the way was just to use the correct function for the job which is not set vector as the error message was trying to hint to me but rather set ins programming can be such a joy sometimes anyway with those chunks in place i have been working a bit on the terraforming this was actually really simple i just cast a ray out from the player to see where that hits the surface and in a little sphere around that point i then add or subtract values from the map depending on whether the left or right mouse button is held down and then of course any affected chunks need to be regenerated the performance is still not that great with the main bottleneck i think being reading the data from the gpu back to the cpu to construct the collision mesh if i take this experiment much further i'll definitely need to address that but a more pressing concern is that if i try to terraform by my feet i immediately plummet through the surface to the depths below so i've added some extra checks to the player controller for when nearby terrain is modified and it's still a little wonky but definitely a step up from before what's bothering me the most right now is how dull the planet is to look at so the first thing i'll do to try to liven it up a bit is generate a sphere to act as a simple ocean layer it's not looking all that watery at the moment though so it's gonna need some work i'll start by figuring out how far we're looking through the water to the terrain below and we can do that using the camera's depth texture which tells us how far away from the camera each pixel on the screen is the water itself hasn't been included here because it's using a transparent shader and only solid geometry is included so in the water shader we can take the depth value of the current pixel and subtract from that the distance to the water pixel we're currently drawing and that lets us visualize the distance that we're looking through the water what we can do now is take that value and use it to blend between a shallow color and a deep color like this and here's what that looks like that's looking a lot better already i think the water is still completely opaque though so i've been fiddling around in the code a bit to make it more transparent when viewing from a steeper angle and also to have it be quite transparent in shallow regions like along the shoreline i've maybe made it a bit too clear now but can always be tweaked later next i'd like to make the sunlight reflect off the water so i'll use this bit of code for my old planet video for calculating a specular highlight it's a bit intense at the moment so i'll tone it down to something more reasonable i think i'd like it to be more stylized though so instead of allowing the intensity to fall off smoothly i'm going to split it up into three bands with this bit of code and that takes us from this to this it's looking a bit odd because obviously the water shouldn't be so flat as to give us such a perfectly round highlight so i'll try scrolling a normal map like this one across the surface to fake some little waves if i increase the influence of that normal map we should see it start to break up the reflected light rather nicely these fake waves only affect the light though so i want to add some larger waves that actually move the vertices of the mesh i've been messing about in the vertex shader for a while fiddling with sine waves but if anyone knows a good approach for handling waves on a sphere i'd love to hear it because what i've ended up with here looks pretty ridiculous although if i scale these way down they do at least do a good job of breaking up that perfectly spherical outline that the ocean had before the last thing i want to add to the water for now are some simple foam lines around the shore but for that we need to know how far away the shore is so remember this 3d map texture we have this actually gives a good approximation of how far away the nearest surface is from any point in space the values aren't literally distances because they change at different rates in different places but if we visualize them on the surface of the water we can see that the darkest values are all around the show and so we can easily isolate a little band like this i then messed about with that for a while applying sine waves that move over time and breaking it up with some noise until i eventually stumbled upon a result that i was at least reasonably happy with i'm a little hesitant to show the code for this because it's a real mess i wrote this just the other day and i already have no idea what half these numbers are supposed to do anyway i'm just going to play around with this a bit and try figuring out where to go from here i also wanted to show the strange looking results i got when i accidentally increased the resolution of my water mesh beyond what the default mesh settings allow but that was easy to fix with this one line of code i think what i'm going to do next is add an atmosphere to the planet thankfully i've already done a project and video that goes into detail on that exact topic so i can pretty much just drag and drop the files from there the only issue is the atmosphere is sort of eating the water and this comes back to the fact that the water isn't included in the depth texture but after some research i found that i could set up a second camera dedicated to only drawing the water's depth texture the two depth textures can then simply be combined into one and now the atmosphere works so all we need to do is find a nice picnic spot and watch the sunrise [Music] something else i could probably add relatively easily are the clouds from another of my old videos this will take a bit more work because they weren't really designed with planets in mind basically the clouds are contained within a big box in the sky but i've been tweaking this to instead use a sort of spherical shadow right now the results are a little dubious but i feel like i'm headed in the right direction maybe after some more work this is now looking a lot better i think although if you look closely there's still a bit of weirdness going on also the performance is far from amazing especially for dense cloud coverage and ideally the clouds should be integrated into the atmosphere so that at sunset for example let get a nice orange glow but my first attempt at that met with little success i think rather than trying to hack these two shades together at some point in the future i'll work on a new and improved version of both that play nicely with one another so for now the clouds are essentially just pasted on top so the lighting doesn't really work when it's not data [Music] i reduced the detail of the clouds a bit to try make them fit in a little better with the fairly low poly terrain looking at it though i'm wondering if the clouds shouldn't be a completely different style for example i just remembered this old experiment looking on my hard drive perhaps something more along those lines could work anyway for now i just want to add some color to the terrain one idea i had was to again take our 3d map of values and make a copy of it at the start that's unaffected by the terraforming then by sampling that in the terrain shader we can figure out if we're inside a tunnel that the player has carved out and make that a different color it's usually pretty dark inside tunnels so i've made something called a sticky light which you can throw to illuminate an area [Music] [Music] i'll also calculate the steepness of the terrain essentially just by taking the dot product of the direction from the center of the planet to the current pixel and the normal vector of that pixel we can then do some simple coloring based on that steepness value for example giving flat regions a green grassy color and steeper areas a more rocky brown color i've also added a bit of noise to the colors to just give a tiny bit of variety with that done let's take our intrepid little astronaut out on an expedition [Music] so this has been a lot of fun to work on but obviously a massive challenge still remains in terms of making the world actually be interesting to explore because it essentially looks the same right now everywhere you go that's something i might attempt to tackle in the future time will tell for now though i hope you enjoyed the video and thanks for watching cheers [Music] well that's stuck in my head [Music] you
Info
Channel: Sebastian Lague
Views: 316,252
Rating: 4.9894214 out of 5
Keywords:
Id: vTMEdHcKgM4
Channel Id: undefined
Length: 22min 23sec (1343 seconds)
Published: Sat May 29 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.