UE5.2: PCG - Apply TRUE Density Scaling

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello fellow Unreal Engine artists designers and developers in today's tutorial we'll be creating a true density function in procedural content generation we'll be taking the density values of our points and converting them into a real density of points in our PCG regions we'll also be using density to affect the scale of our points and finally putting both techniques together to create a density and scaling feature which helps create natural looking falloffs in your level and all of this just using PCG nodes no blueprint programming required let's get into it [Music] let's do a quick recap on what density is in procedural content generation if you look at a set of points in a procedural content graph then you will see that each point has a density value and by default that density value is set to one if you do a debug on the points you will see that density value is represented by color so a density value one is white density value of zero is black and then various Shades of Gray in between now there are various ways to manipulate the density with different functions you've got things like normal to density height density and in things like the spline sampler you can even draw graphs of density so that gives you the ability to vary the density from the interior to the exterior or the exterior to the interior so I'll give you an example here in my spline sampler I will add a key point at zero with a value of one and I'll add another one at time one with a value of zero so that's a linear drop off between the interior of the spline and the exterior of the spline and if we save this and regenerate the the graph here then you'll see that we now have a density of one in the middle of the spline and then as it goes out it's dropping off from 1.9.8 until it gets to the end of zero so these are the density values but out of the box they don't actually do very much well I say they don't do very much but there is actually one effect that you may not be aware of with density and that is that if you have a density value of zero or negative then the mesh spawners won't spawn anything so I'll give you an example of that if I come back here let's switch off my debug so we'll open up our density falloff curve and I'll add in four new points and I'll drag some of these ones down in the middle so they're below zero and now if I save and I regenerate that you'll see that I've got an instant crop circle so anything with the density of zero or less will not be spawned in the mesh supporter so that that's one effect but other than that density is really used for things like filtering operations so you could say if density is greater than a certain value then go off and spawn different meshes so you could have trees in the middle and then grass on the outside however what I'm going to show you today is how to create a function in the PC key nodes that actually converts the density values into something more useful so for example if the density is one it spawns all the points if the density is 0.5 it only spawns half the points so density becomes a true density function and we'll also use density to drive scale as well so the denser points will be at full scale and the less dense points will be smaller in the in the mesh spawner so let's get straight into doing that so let's start off by creating a true density function where the density value actually drives the number of points that are generated in that area so the way we're going to approach this is we're going to Generate random values between 0 and 1 and if our density value is greater than that random value then we'll let the point through otherwise we'll prune the point and that will have the effect of letting all density of 0.1 half the values of 0.5 etc etc so the way to Generate random values between zero and one in the in a node is using the density noise now that poses a slight bit of a problem because it's a density value that we actually want to use so first thing we need to do if I what I'll do is I'll um I'll put this these nodes between the transform points and then the mesh spawning here so the first thing we need to do is we need to back up our density to another attribute so let's drag out here and we'll do an attribute operation and this attribute operation is going to take the density and we'll create a new attribute called original density so that will effectively back that up and then once we've done that we'll then do a density noise function and this density noise function will generate in this case if I use the set function will Generate random values between zero and one so that will overwrite our density density attribute now what we need to do is we need to see if the original density is greater than this generated density so for that we will do a Point filter and the operation is greater than so what we want to see is is the original density greater than our random value and if it is then we'll let it through and so the last thing we need to do is just restore this original density back to the density attribute so drag off here do an attribute operation and we'll do the reverse of what we did here so we will copy original density back into in fact you can just use this plus and pick density I should make sure you change that as well so original identity back into density and then we'll plug that in here use alt to disconnect that so let's just recap where copying our density value into original density then we're generating random values between 0 and 1 in that density value if the original density is greater than the random value then we will let it through so if it's not nothing will nothing will happen and effectively the point will be discarded and then we will restore the density so let's do a quick test of that so do a control save let's come back to our element here I've removed the zero points in the curve here so that should disappear but let's do a regenerate let's do a cleanup generate and you can see that we're getting some density a function going on here so in the middle the density is staying the same and then if you go out outside it's getting less and less so you're getting fewer points on the outside so that's a good first start so the next thing I want to do is I want to also use the density to drive scale as well so that the where it's densest the scale stays the same and as the density decreases the scale decreases as well so this will add to this effect of the meshes getting fewer and smaller as they go out so let's do that now so getting the density to affect the scale is a very simple multiply operation so after our identity nodes here let's add a new node a maths node and we want to make this multiply and what we'll do is we will take the scale we'll multiply it by the density and we'll output the scale so if the density is one here the scale will be unaffected if the density is 0.5 the scale will be halved and if the density is zero the scale will be virtually zero so let's just now connect that to the mesh spawning disconnect everything else and let's um save and test this out so if I do a generate we have an error ah so this is a common thing when you do things that have multiple nodes in make sure that you connect your point data set to all of the nodes so because I'm using scale from the point set and density from the point set I need to make sure this is something that catches me out regularly so this should sort the problem out save regenerate and there you see now as well as the density being filtered out we also have to scale being filtered by density with the full scale in the middle and the small scale than the outside so this is working well but it's rather digital at the moment so you either have all or nothing so what would be useful is to add a couple of parameters in the main blueprint that drive the effect of the density value and the scaling value so let's start off adding a new value to our main blueprint so if I edit the main blueprint here and what I will do is add in a new variable and I'm going to call this variable density reduction a type of float and make it public and visible compile it and the default value is zero so the way this is going to work is oh I haven't spelled it correctly so correct my spelling error here so the idea here is that the if the density reduction is zero then there's no effect on the density at all if the density reduction is one then it's the full effect and we can even maybe change the values not only in between but higher as well so let's use this in our graph so go back to your graph and what we'll do is we want to use that to multiply the density noise so actually let's just take the scale bit out temporarily so we only see the effect on the let's um remove this and just connect the density output directly so we'll we'll reconnect the scale again in a minute but then we can just see the effect on the density so what I'm going to do is create a little bit of space here and then from the density noise I'm going to do a multiply so it's a maths up so connect that into here and so we want this operation to be a multiplication and we're going to get our property from the blueprint so get active property and the property we want to get is density reduction if you don't spell this ride you'll get an error and then we'll plug that into the other input here so let's explore how this is going to work so density noise is generating values between zero and one if the density reduction is zero and we multiply it we'll get zeros out all of the points will be above zero so all the points will get through if this value is one then it will be as if the density noise went straight to there which was our original idea and if it goes higher it will actually reduce the points even further so it's actually quite um quite useful function to have this property so let's uh do a save go back to our main scene and regenerate and at the moment we're not seeing anything that's have a look see if we've done anything obviously wrong yes I can see what I'm doing wrong here so in the multiply here I'm not actually specifying what I'm multiplying and what the output is so we're multiplying the density from the density noise that we don't have to name this because that's coming in on the input and the output is going to be the density so that should sort the problem out I'm back here regenerate okay and we now have a because we've got a value of zero there's no density reduction taking place at all if we make the density reduction one we've got the effect we had before we can now even increase it more three four five or have it in between so like fractional values so we've got more control over it so that's worked well for the density let's now parameterize the scale function as well so for the scaling control we want to go through a similar process so let's start off by adding a new variable to our blue main blueprint so we'll add in one called scale reduction do a compile and we'll set the default value to zero like before and now let's switch over to our graph and reconnect the parts of the scaling functionality so I'm just reconnecting those so what we want to do is we want to add a similar function to adjust the scale before we go through the multiplication by density now this isn't as simple as the as a multiply the reason for that is that what we want to do is if the if our scale reduction value is zero we want the multiplication here to be by one regardless of the density and if it's one we want it to be the density so in fact what we need is to do is a linear interpolate function so let's create a little bit of space here let's disconnect these for now and so out of here we will do a maths operation and the math and then we can connect the output to these two again and the maths operation we want to do is a lerp and so the ratio is the property that we've just created so let's do get back to property and the property name is scale reduction and this will be our ratio so now we want to set this up so that if this is zero we take the first value here so that's we want that to be one if this is one that we want to take the density so this is something that might catch you out you um you might be tempted to do this so you might be tempted to disconnect this connect this to the second input then create an attribute with a value of one float one and we'll connect that and then in the lurp you say input source 2 is density and then the output is actually we need to create something new here because we don't want to overwrite the density so let's call this scale density and then in our multiplication we will use the scale density that way we don't affect the actual density values for any future operations so you might be tempted to do this now the problem is this won't work and as far as I can tell I may be wrong here but as far as I can tell but with any node here you have to plug the point data set into the first value here so we need to have something like this the problem here is that we then need to find a value of one for this so I mean there might be values of one here and in fact there are things like the color values if I do a inspect here you can see that things like color values are one but you can't really rely on that so let's um instead let's create a new attribute in the point set so let's get rid of this from here we will do add attribute and we'll add an attribute called No scaling which is a float of one and then we'll plug that into here so you've got that and you've got an error at the moment simply because we've been playing around by putting other attributes in that should that should correct itself eventually once we regenerate so that looks right let's just again quickly recap what we're doing here so we're um getting our scale reduction value it'll be between zero and one it might be higher than that but we'll address that in a minute if it's zero we're going to use a value of one here if it's one we'll use the identity value so you can see in the lurp here that the input sources in fact we want to change the input source one to no scaling that's the new value that we've created so zero will become a value of one one will become the value of density and then we're going to Output a new attribute of scale density and then our multiplication will now use that as the multiplication Factor so let's do a save let's go back to our element here oh we haven't made the scale reduction visible so we must make sure if we go to the blueprint that we make the scale reduction public and visible recompile and save and then if we come back here you can see at the moment with the values of zero and zero there's no change to density there's no change to scale if we make the scale reduction one you can see now the density isn't changing but the scale is varying from one in the middle to zero at the end and we can now do in between values 0.5 0.6 0.7 0.8 so it has incremental values so we're almost there with this um the there is one problem with the scale value which is that if you go above one let's do two what you can see is that some weird things are happening on the outside and if you actually explore in Greater detail you'll see that actually there are upside down measures there and the reason for that is because the um the mathematics of that interpolate as it goes over one it starts to create negative values so the easiest way to fix that is to just to clamp the output of that so that it stays it never goes negative so let's go back to our graph and we'll simply add another element in between the lurp and the scaling multiplication so come out of here do another maths up and this up will be a a clamp minimum so let's disconnect here so Cloud minimum the value we're clamping is this this one we just created the scale density so let's put scale density as the we want to clamp and the minimum value here is zero so we need to just create an attribute which is already zero and plug that into the minimum there and then we'll reconnect these so this will ensure that we never get a negative scale density value so let's save that go back and let's do and regenerate so you can see now with a value of two here where we were getting some negative values the outside we're not getting that anymore so we can now go happily go up to whatever we want and it will slowly remove everything so this is working really nicely and the the benefit of having these two values here which you can start to mix them together to get the effect you want so for example you could make the density reduction half here you could then make the scale reduction 0.8 and you can see you get nice interplay between the density reduction and the scale reduction there gives you a good good control over the look and feel of the different areas you're generating so the final thing I want to do is this is a useful function that we could add to our library and reuse elsewhere in other graphs so what I want to do is I want to collapse all of this into a sub graph with parameters so to create a reusable function or a subgraph of these nodes what we need to do is select all of them in the graph right click on one of the nodes and do collapse into subgraph and we'll need to save this as something here so let's call this dynamic density I'm saving in my PCG nodes collection and you can see now it's completely collapsed into one node in the main area here so if you look at it it's it's created the inputs and outputs as the names of the first node and the last node so there are two things I want to actually have it just going to In and Out and also the two parameters that we got from the main blueprint I'd like to take these out of the function and connect those as well so that's quite simple to do let's double click to open up our Dynamic density function and first thing if we go to the settings graph settings let's do exposed Library first so that we can see it over here and let's put it in a category of filter do a save and you'll see now over here in the filter section we've got our Dynamic density sub graph we can drag in uh next thing we want to do is affect the nodes that are here so if you go to the input let's delete the node that it's created and then reconnect the in and then similarly on the output node let's disconnect that and connect it here and the other thing we need to do is we need to I want to take these two parameters out and connect those and have those as parameters here so go back to our input node what we need to do is add a new custom pin and this pin will be let's call this density reduction and the type is attribute set and we don't want to allow multiples here so let's just disconnect that and let's duplicate this and call this second one scale reduction and that's also an attribute set so once you've set those up here we want to delete these two get active properties and we're now going to connect the density reduction to this first multiplication and we're going to connect the scale reduction to the lurp ratio so now all we need to do is make sure that these values are provided to the function so do a save here go back to the main graph here and now we will connect our in and out and we will do our get active properties here this makes this nice and self-contained so we can have different properties so get active property density reduction and then duplicate this and we want to change this one to scale reduction and plug that into here so all the effects should be the same but now if we wanted to use Dynamic density in another graph we could just drag it in and connect the density reduction and scale reduction or even set them directly within the node so let's do a save here and let's quickly test out to make sure nothing's broken go back to here let's set everything to zero again zero and zero so zero and zero there's no change fully dense fully scaled let's use the scale reduction of one that seems to work let's do half the that and let's do density reduction of one yeah so that all seems to be working as before so I hope you found today's tutorial useful uh stay subscribed for more tutorials in the future and I'll see you in the next one bye for now
Info
Channel: UnrealityBites
Views: 10,733
Rating: undefined out of 5
Keywords:
Id: zWFn1EBl94A
Channel Id: undefined
Length: 27min 0sec (1620 seconds)
Published: Tue Jul 18 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.