Voronoi-based Lava in Unity Shader Graph

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
voronoid diagrams are super useful in computer graphics for generating patterns that resemble things like rocks or a collection of cells and the 3D equivalent is used for destructible geometry it also works great for generating a lava surface like this one so in this tutorial I want to show you how the vorinoid function works then use it to create a lava Shader completes with emissive lava streams and solid shrimps of rock in between check out the GitHub repository which contains all the files you need for the effects or follow along if you want voranoi works by Distributing control points on a plane then for each position on the plane we work out what the closest point is and do something with that information sometimes people color each pixel based on which control point was closest and other times people color each pixel based on the distance from the closest point we're going to color pixels based on the distance from the closest I entry between regions which is a bit more difficult but definitely doable in unity Shader graph comes with a voronoi node which outputs two things the distance from the nearest control points and a random value for each region which you could then turn into a random RGB color however it doesn't output any information about the edges separating those regions you can try and extract information about the urdlers perhaps by using a ddxy node which finds gradients between adjacent pixels but that's well it looks bad and you can't customize the width of these edges at all to get this Edge information we'll need to write our own custom voronway node with an hlsl final which you'll need to create with an external text editor just to make sure you give the file the hlsr extension if you're allergic to code and you just want to use Shader graph then the file will be available on GitHub along with the rest of the product so just copy that and skip to the next section of the video my custom node will output the distance from the closest control points and the distance from the closest Edge but not the random value for each region which Shader graphs for annoy outputs I'm basing this on Code by Inner girl Killers a fantastic shade of person who's been doing this longer than I've been alive I've linked the relevant article in the description essentially we divide the whole plane into cells of equal signs and generate a random control Point within each cell using the lower left corner position of the cell as a random seed every time you input the same Corner position into the render function you get the same control Point position I stole the random function from shadergraph's built-in 409 node implementation for each pixel we run two passes over the cells first we set a distance from Center variable to some arbitrary large value then Loop over the nine nearest cells where the central cell contains the pixel if the distance between the pixel and the self-control point is less than distance from Center then we overwrite distance from center with that distance value and remember the offset vector between the pixel and the control point that will be important later after the loop finishes distance from Center gives us the same output as Shader brass built in for a noise node the second pass attempts to find the second closest control point if the first closest and second closest control points are an equal distance from the pixel then the pixel rests exactly on an edge so the second pass sets a distance from Edge variable to an arbitrarily large value and then we Loop over the same nine cells as before if this cell contains the closest control point then this normal lace function tries to normalize a zero Vector because the offset is exactly the same as the one we kept track of in the first Loop so it returns infinite and this line evaluates to a huge number it's a really smart way of filtering out the closest cell because we're trying to find the second closest cell anyway if it's not the first supposed to sell this line finds the distance of pixel from one of the edges and if it's smaller than the distance from Edge variable will overwrite distance from Edge and thus the custom code sorted now it's time to work this into Shader ref somehow and actually make the lava effect with it in unity I made a new graph via create Shader graph urp lit Shader graph and named it lava inside the graph I'll begin by adding a custom function node then I'll drag the custom vorinoid.hosl file onto the source field here the name should be the same as the hls all function we wrote minus the underscore float bit so that's custom borrow noise then we need to add the outputs and inputs to match those views to the function the inputs are the same as shaded brass built-in raw annoy node being a vector 2 UV and two floats called angle offset and cell density then the outputs are two floats namely the distance from Center and distance from Edge that we calculated in the code we're going to create the graph outwards from here as there are parts that come before and after this mode for the shape of the rock islands and the width of the lava channels we'll need five graph properties all of which are floats the Island's density will control the size of the cells we use in our calculations which in turn impacts the physical size of the rock Islands the angle offset is going to control how far the cell control points move from some start point if this is zero then we'll end up with a completely regular grid angle change speed controls how quickly the angle offset increases if we want the rock Islands to change shape over time then set this to something above zero finally we have the thickness which refers to the width of the lava channels and the thickness fall off which blends the lava and The Rock slightly for our custom 409 node angle offset let's multiply our angle change speed property by time and add the angle offset property now the shape of ourselves will change over time if you set the speed above zero the cell density input can just use our Euler's density property for now if I use a UV node in the UV slots you'll see the preview animating but we'll do something more complicated for the UVS later next we'll be using the distance from Edge output and applying a threshold specifically I want to use a threshold with a slight fall off so that we can have a small transition zone where the rock turns into lava so I'll use a smooth step node for Edge one I'll use the thickness 14 and for Edge 2 I'll add thickness to the thickness 4 or 40. then for the invalued I'll use distance from Edge from the custom varanoi node this gives us a sort of mask that we can use to pick between display and block and displaying lava next I want to go back a bit and modify the UVS we use for the custom 409 node even if you set angle change speed to zero I want there to be some animation where the large channels wiggle a bit to give the impression that there are some warmer currents flowing through the channels or something like that I'm not a geologist around three main properties one is a flow map which is a texture 2D which contains essentially directional information about which way each part of the lava will flood the other two are both floats the flow strength and the flowing speed which represent how far the lava gets displaced and how fast the Shader Scrolls through the flow map the key thing for the flow map is to enable used tiling and offset in the node settings because the flow map I'm using is quite low resolution and I want to tile it let's multiply the flow speed by time and add it to a UV node then use the result to sample the flow map texture this collection of nodes will scroll the flow map over our mesh but we're not doing much with the values yet each pixel to the flow map contains a 2d offset value that I want to apply to the UVS I use for the custom vorinoid node so first multiplied by flow strength then add the results to another UV mode and use that result in the custom romanoi node now we have the ability to add wiggle there are three things remaining sorting out the Rope colors the lava colors and changing the lighting by modifying the normal Vector let's start with the Rocks I'll need two properties for this A rock color and a rock texture in my products and in the GitHub I am using Rock and lava textures from ambientcg.com which is an excellent source of CZ zero textures essentially a license which is very similar to putting something in the public domain I'll take the smooth step mask from before and use it for the interpolation Factor T value of a lap node for the a slot I'll use the color black so anywhere that's black on the mask is lava and we don't want to use Rock colors for the B slot I'll sample my rock texture property and multiply by The Rock color property the lurp output can be used for the graph's base color outputs because our rocks are regular objects that should have lighting applied normally for the lava it will look slightly different I'll add lava color and lava texture properties but I will also add a lava speed Vector too which will allow us to scroll the lava texture this will make it appear as if the larva itself is flowing through the lava channels the lava color should also have HDR enabled so that we can make the lava glow as you would expect from lava similar to how we dealt with the rock areas I'll use the smooth step mask in a lot mode this time I want to Discount the white areas of the Mask so the B input should be black for the a slot I'll sample the lava texture and multiply by the lava color but this time I'll also modify the UVs take the lava speed and multiply it by time then use the results as the offset of a tiling and offset node which should then be connected to the UV slot on the sample node the result of the lob should be connected to the emission graph output which means you'll see the color even if you place the lava in a really dark cave or at night time Vance just leaves the normal Vector currently the rocks are all totally flat so it would be nice to add a bit of shape to them and the easiest way I can think of is to apply a normal mount to the Rocks I'll do that by using the voronoi pattern and turning it into a height Mount from which we can generate normal vectors we'll need a new float property called height map strength for this if we take the distance from Edge output from the custom vorinoid and subtract the thickness then anywhere on the surface that should be Lava will have a negative value represented by black on the preview then with a saturate node we can clamp those values to zero that ensures that the lava areas will be flat while the rocks will be raised we can use a normal form height node with the saturate output and the height map strength property which generates a normal amount with these trippy colored patterns on the preview window and to finish off the graph let's connect its output to the normal block on the output stack oh and one last thing I forgot set the smoothness graph output to zero back in the scene view all we need to do is apply a material to any object and we'll see the lava working as intended as long as you have a blue filter set up in your scene which is possible in all Unity pipelines the lava will glow if you use an HDR color with an intensity above zero thank you so much for watching money patreon supporters are scrolling down the screen right now if you become a patron today then you can get early access to every shade of video and bonus copies of my premium Shader packs on etch until next time and always have fun making shaders
Info
Channel: Daniel Ilett
Views: 5,084
Rating: undefined out of 5
Keywords: unity shader graph, unity shader, lava shader, voronoi function, unity voronoi, voronoi noise, hlsl, shader, gamedev, voronoi lava, worley noise, urp, hdrp, unity urp, custom function, unity node, shader graph node, rock shader, magma shader, voronoi magma, voronoi rock, voronoi shader, voronoi hlsl
Id: pFQ2-HFG_hY
Channel Id: undefined
Length: 12min 27sec (747 seconds)
Published: Tue Jun 20 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.