Houdini - Procedural Modeling Tips! - Slope Reduction for Paths

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
howdy guys handypixel here and in this next procedural modeling tip video i wanted to go over a topic that was brought up by one of my patrons and the topic was about how do you go and level paths for your game levels or your terrains after a designer is you know laid down the curve how can you automatically you know make sure the path fits within a max slope threshold so it doesn't you know go up to like 80 degrees and so what we're going to do in this video is we're going to cover that particular topic and what we're going to do let me actually stop this here what we're going to do is we're going to cover two methods we're going to do a really quick and dirty version that really just involves blurring um the path and then we're also going to go over and cover how to do it with a soft solver all right so a little bit more advanced i would say a little more accurate um and so yeah let's uh take a look and see how to hook this whole system up all right so let's start out our slow production by dropping down a geo node here inside of houdini and i want to create a curve and then i want to create a height field and for this height field i want to also add some noise just so we have some sort of terrain to work with because we want to try to reduce the slope on a walking path on a terrain and so we just need some sort of random terrain uh in here you can go and offset the sky use the increment ladder there to move this thing around to find some interesting terrain looks pretty good i'm not going to be too picky about it i'm going to hit uh spacebar 2 on the keyboard to go into my top view and i'm going to select the curve node here and just template my high field noise and then with the curve node selected i'm going to put my cursor over the scene view and hit enter to edit enter into its edit mode and let's just go and create some sort of locking path i just want to make sure that it covers a good portion of the terrain here beautiful and then i'm going to resample that and what we're going to do is we're going to put a point every meter so i'm going to set the length on the resample node to 1. and let's also go and turn on subdivision curves just so we get a nice smooth curve out of that let's hit spacebar one on the keyboard to go back into our uh perspective mode here i'm going to hold down control and then click on the template flag just so i can display both the terrain and the curve at the same time cool all right so on the curve itself inside of this resample node i'm going to go to the tangent attribute and turn it on and i'm going to actually replace that tangent u attribute name with the capital n and what that will do is put the uh the normal direction or the flow normal of the curve onto the curve here so it's kind of hard to see right now if i go to my guides by hitting d on the keyboard to bring up this display option window and scale the normal to 1.73 there it's still kind of hard to see let's actually turn off the height field noise so you can kind of see it if you go all the way to the end of the curve you can see a little normal poking out there so yeah there we go all right so what we need to do first uh to get an idea of the slope of the train is we need to snap this curve now to the train itself and i'm going to do this a little bit differently there's a couple ways you can do this so you can do this in a wrangle node or you can use a race op over here and the raceop uh needs to use a vector not the normal so let's do this and uh i just did a control shift to remove the expressions and then i put one into the ray direction then i have to copy this ring node so i do an alt left click to copy it and then on this guy i just switch the normal direction to negative one so there you go so now i have the curve snapped to the terrain so that's how you do it with the built-in soft nodes there with the rain node i'm going to call this snap to terrain uh the other way we can do it is and it's a little bit faster especially when you're working with the houdini engine is to actually sample the volume information from our height field remember that these height fields are volumes themselves they're just set to display if you actually dive inside the height field node you can see that it's just a volume bop and it's generating a volume right just like if you were to go and create a volume itself right here right so that's the same thing basically and so what we can do is we can actually pull off the height information if you go to your geometry spreadsheet for the terrain itself here if i click on this guy you can see that it has this height name and this particular volume has a couple intrinsic primitive attributes on it so if you turn on volume in value and my volume max value you can see that we have this min and max value so negative 96 to 90. those are those height values on a per voxel basis inside of the volume so we can do is we can sample that information inside of a wrangle node here so let's actually take a look at how to do this all right so the first thing that we need to do is we need to create a new sample position and the sample position is going to be the position of the point the current point coming into this first input here and so i'm going to do we're going to say set and i'm going to do at p dot x and 0 and at p z all right so the reason why we don't want to pull in the y position of each point is because these volumes are sampled in a 2d space right so z 0 is going to be or y is going to be 0 here all right and then we need to get the primitive id that we want to sample and to do that we use the name to prim vex function and we want to sample the height volume that's coming in so remember if you click on the height field here it's creating this height volume and it has a min and max height value of negative 96 to 90 there all right so then finally all we need to do is we need to sample the height value from our volume so we use a volume sample like so there you go and so we want to sample from the geometry coming into the second input or input one and we want to utilize the prim id so that's the volume that we want to get so what happens is this named friend function basically looks for any volume that has a name of height and returns the primitive id or zero in this case all right and then we want to give it the sample path so where do we want to sample inside of that volume that'll give us the height right so let me actually turn on the display flag for the curve here so you can see we're not snapping yet we're completely flat so now if i were to take that sampling value and uh pump it into the y position for our points so i'm just going to say height you can see that we automatically snap and like i said before this is much more efficient and faster when you're working with the unity engine stuff but it's also here in santa fe needs a lot faster the rain nodes work too i just tend to do this more often and what i do is i once i get the code written out i go and create a preset so i say save reset so you can see i have my volume height sample there all right so i just wanted to point that out all right so at this point i'm going to resample this again now that we're snapped this helps to basically make the system run a little faster because we're working on less points i'm going to actually set this race sample to a length of 10. i find it good to start with larger values for their sampling and then you know you can work your way down to smaller values something like this we're going to stick to 10. all right so that basically is the first step in getting this working so we snapped it to the train so step one is snap to turn and we learned a little bit of x in there as well all right so let's move on to the next one our next step is to uh try to figure out how to um find the slope of the curve right so we want to find you know what slope are you you know trying to walk up this particular path here and so before we dive into all that i want to explain you know how this works for those of you who might not know so i'm going to call this angles example and what i want to do in here is set up a scenario here we have two vectors all right so i'm going to create two points here let's turn these guys on and keep them at the center there using an add node and um then i'm going to split so i'd have two points and i can create two different vectors so i can work on them so i'm just going to split on point zero we're going to set this to points here and on the first point coming out of the side of the split node i am going to put a new normal on it and to do that i'm just going to do a 0 0 1 for normal direction in z so if i zoom in on this point it's really tiny so now we have a normal that's pointing in the z direction here so i'm just going to copy that and do that for the other point over here and then drop down a wrangle node what i want to do is i want to kind of reverse engineer the slope um calculation for you guys so you guys can see how it works and so for this to work we need to have two vectors that have a different direction right so we're going to use these two vectors here to find the angle between those two and so in order to do that we need to have two vectors that are pointing in different directions here so i'm going to rotate this particular vector over here that's on point two all right and so uh to do that i'm simply gonna create a new angle variable and we're gonna make it so we can change it ourselves so i'm going to create a new float channel just call it angle for now and i'm going to create a new matrix because we want to rotate this particular vector and this is going to be matrix 3 and i'm going to just initialize it to identity which is basically no rotation all right and then i'm going to do a rotate function we're going to rotate that rot matrix by the negative angle that we provide and we want to rotate it on the x-axis all right because our our uh normal here is pointing in the z-direction so i want to rotate around that x-axis there so that's what we're going to do and then all we need to do is say at n times equals a rat there we go so now we need to go and expose our parameter there and let's start to add some values into this guy now you're going to see that we're going to go crazy here and that's just because our angle value we want it to be in degrees but these most of these functions here in here take radians so we need to convert those two radians over here there we go so now we can go and change the angle of our normals pretty cool so now let's say that all we're given is two vectors right so a lot of times this will come up when your procedure modeling adventures if you will you'll just be given two vectors you need to find the angle between those two uh we don't know the angle up front right so i'm going to set this to something like 50 degrees and let's just uh go through that scenario now so how do i go and find the angle between these two vectors all right well it's pretty simple actually let's just drop down an attribute wrangle node here and i'm going to feed in my first point so this is the vector i want to compare against and this is the vector that i want to compare with over here all right so i'm just going to feed that into the first input and in order to do this i need to get the normal so we're going to call this the other normal from the second input there or input one so we want to get the n attribute from point zero there's only one point in this particular stream so it's point zero all right so uh how do we find the angle well we know let's actually start with this so uh we know that the dot product so if i do the dot product of at n and other other normal over here this returns the cosine of the angle between two vectors all right and so to find the angle from the cosine we just need to do the arc cosine so we say a cos so our cosine like so now this will turn it in radians as well so we need to convert it back to degrees like so and if i do that you can see that our angle so let me actually template this guy here so our angle is 50 degrees and if i were to go and change that angle you can see let's go and set it to something like uh 65. when we come back down here you can see we have 65 degrees all right so that's the general idea of finding the slope on a curve and getting it back into something that's readable the actual angle all right so let's move on now and uh start working on our slope reduction so now that we know a little bit more about uh how to find slope on geometry in general on points hearing like that stuff like that uh let's go and drop down a wrangle note here so let's go find the slope of our curve here so we're going to call this get slope and inside of this guy we are going to go and find the slope of this particular curve here so uh what we have to do first is we need to create our reference uh normal so currently on our resample node we actually forgot to produce the uh normal so let's do that so we need our flow normal first so that gives us a normal that follows the direction of the curve uh then we need to go and create a reference normal so this reference normal is just going to be flat so like just like we saw in our last example we want to flatten out the current vector the current normal vector so this is going to be equal to at n then we're going to say flat norm dot y is equal to zero and then we want to normalize it just to make sure it's of unit length so we'll see normalize and normalize flat norm there we go all right cool so now we have two vectors that we can compare uh to find the angle right so all we need to do is say f at slope just so we can store an attribute on these particular points that's why i'm creating an attribute here that's equal to degrees and we're gonna do the arc cosine so a cos of the dot product i can type today so we want to do the dot product of um at n and our flat norm there we go cool and then what i'm going to do is i'm going to colorize this so i'm going to say at cd is equal to 0 000 just so we can visualize our slip knit you can use a visualize node as well but since we're here i'm just going to do it all inside the same box node here so or the wrangle node all right so i'm going to say that we want to clamp this by some sort of max slope value so we're going to say max slope if it is greater than that max slope we're going to color you red so 1 0 0. there we go let's turn it on and let's take a look here all right so let's go and create our max slope value and as i increase the slope here you can see that we're finding where the maximum slopes are all right so we're going to leave this at let's say something like 15 degrees so how do we use this information now to reduce the overall slope inside of our curve over here well it's pretty simple so there's a couple ways um i wanted to show you guys one of them is just going to be kind of like a brute force approach and the the second uh approach is going to be a soft solver so we're going to you know actually do a little bit of a simulation for it so the brute force approach here is just a blurred out so i'm going to do an attribute blur let's drop this down i'm going to blur our cd value here i'm not going to pin my border points and actually we should pin the the ends here so let's actually do this here on the same wrangle note here so this one is to find the slope and this one is to find the ends so in order to find the ends i'm going to do a new variable called naycount and we're just going to get the neighbor count i believe i showed this before in one of the previous videos here so i just want to get the neighbor count from our incoming geometry now if the neighbor count is equal to one that means you're an endpoint this really just works for curves so if you go to one then i'm gonna set you on a group called ends like so all right so if i look at my groups and attribute lists and i go to points you can see i have two points at the end there that are now gripped so we can pin those guys i don't want them to move at all and so we need to put that in this attribute blur we need to put that into this guy and just put an exclamation mark in front of it to say not so basically the inverse of the groups ends so all the other points all right so what i want to do with this guy is i want to go and blur out the color so you can see that's just going to create a nice little fall off and you can do you know however much you want there all right and then finally we're going to do an attribute blur for this guy and we are going to just blur out um all the points here except for the ends again and we want to create this weight attribute so this weight attribute basically takes a 0 to 1 value so it's going to blur it more where it's one so we can use this color attribute here so actually add cd and let's turn off pin border points now you'll see as i smooth this out some more or add more blurring iterations what happens is it'll blur the areas that are more red and leave the areas that are not sloped alone so you can just keep going with this guy and the cool thing is now if i were to run this guy again here we actually need to produce new points here or new normals i should say so do a poly frame so now if i were to visualize my slope you can see i have just this guy is at that value so if i just keep going you can see we're getting rid of all the sloped areas pretty quickly except for that one larger mountain so there you go so there is your curve so when you are finished with that you're going to notice that you're pretty far off from your original curve right and when you're developing like these sorts of paths for like world building or for game levels and stuff like that you wanted to stick to where the designer actually placed the path so all we're really interested in at this point is the y value of the point so let's just um take the x and z value from the original curve and pump in our new y value and that gives us our final so there's our final slope the final um reduced slope all right so all we need to do is get the position of the um other point so other pause this is equal to points the incoming geometry from the second input and p and that pt num and this works because they have the same point numbers and they're in the same order so they're ordered they're numbered the same and then finally i just want to say p dot y is equal to other pos dot y there you go so we've got the original curve on the x and z but we have our new slope reduction on the y pretty cool all right so that's the first technique and that's like i said a little bit more brute force the reason why it's brute force is because you have to allow the users then to mess around with this blurring iteration value whereas it'd be nice if we had a simulation that would run until all the points were basically below the max slope but still valid let's call this a step two basic approach there we go now let's color this guy and then let's move on now and uh do the uh solver so i'm just going to drop down the solver here these things are very handy for all this let's pump in the first input there and start taking a look okay so let's finish this up by uh looking at the soft solver approach so the first thing we want to do every single iteration that we that we do on this particular curve we need to regenerate the flow normal so let's go and do that let's drop down a polyframe and let's switch the tangent over to the normal there we go so now we have a vector that's pointing along the direction of the curve and then what we want to do is get our slope so since we've already done that let's go and get this guy so i'm just going to go and copy it and paste it over here all right so now we know where our slope is uh we can always actually i already am doing all the visualization super cool all right so then what we need to do is we need to modify the uh neighbor point the height of the neighbor point so let me talk about this a little bit so basically if we're on this particular point right here okay and our point in front of us is less than the max slope threshold then what we need to do is we need to move it down or we need to move it up right so currently we're on this point we want to move this point up and down so that's the neighbor point so let's do attribute wrangle and let's call this modify neighbor height like so there we go and let's jump inside this guy and start typing some vex code for this so the first things we need uh is our max slope so let's create a new variable called max slope and a new channel float so we can modify it so we say max slope for the actual name of the attribute and then i want to also do some sort of height reduction amount so we're going to do a height reduction variable and i'm going to make another float channel for this we'll call this the same so height reduction there we go let's expose these guys and give them some initial value so i'm going to do something like 15 and we're going to reduce it 0.1 meters every single iteration so we're going to either move up or down every iteration through the stop solver here all right so the first thing i want to do is create a weight attribute here so we can visualize it so we're going to initialize it to zero and then finally i'm going to say if um at point so we're going to say if you are not equal to the number of points here so i don't want to affect the end point so the very end of the point here so if you're less than then the point number or the point id so these guys right here so if you're less than that so the end point is going to be 211 so if your point number is less than 211 then can run we can run this operation so i'm going to then check to see if the slope so i'm going to say f at slope is greater than our max slope threshold that we've defined so if our slope is greater than that uh let's get the neighboring point number so i'm going to say nay is equal to at pt num uh plus one all right so what we're doing there is let's say we're on point zero here so if i'm this point so i'm going to say point number plus 1 that means i'm going to get 0.1 because that's the point that we want to modify uh we're going to do a vector and i want to find the neighboring points position in space so let's do a point and we want to get that from zero and we want to get the p attribute and we want to get the current neighbor point number so basically we're getting the position of point one here so let's just pretend we are point 0.0 and we want to get the position of this guy and the reason why we're doing that because i want to see if you are lower or you're higher so if your max slope basically is greater than this max slope threshold and you're lower then we need to move up but if you are greater than that max slope threshold and you're higher then we need to move you down all right so that's what we're doing right there so i'm going to say if at p dot y is less than a poss y then we are going to move you down all right so else you're above it and actually this needs to be a capital p here so just copy well actually yeah this will be fine so basically if you are greater than then we are going to move the point up all right so let's do that now so i'm going to say napos dot y minus equals our height reduction like so so now we're moving the neighboring paws down a little bit more and then we want to move it up on this side right here all right then finally we need to set that point so the neighboring points position using this new neighbor pause here all right so the we need to set it on the incoming geometry we want to set the p attribute we want to set the neighbor point so this guy right here that we got right here so that's the id that we're passing in so we're going to set that particular point we want to give it the new neighboring pause and we want to make sure that we explicitly set it like that like so and we want to do attrib there we go and then finally we're going to say the weight is equal to 1. we're going to use that particular attribute in a actually blur node all right so with this done we can actually watch this work here so i'm going to just do that and uh let's just take a look here we're going to need the timeline for this guy so these guys should start moving up down and stuff like that so yeah there we go so you can see that it's leveling it out appropriately until all the max thresholds are met and we can actually visualize this let's do that really quick so let's go and drop down a visualize node here and we want to visualize that slope attribute as it's changing over time so i want to do a marker let's turn off the update visualizers just so we get one and let's go and find an area over here yeah something like this over here so we can watch it so you can see that we have a bunch of values for slope that are over 15. let me actually run this in real time here you go so now we're going and fixing that until they're all below 15 degrees pretty cool all right one last thing i want to do here and we'll wrap this guy up is i want to do that attribute blur and then i also want to make sure that i retain the original path that was drawn so i'm going to do an attribute blur first and we are going to set this to weight so that's why we created that weight attribute and i'm just going to do this like 10 blurring iterations so every single frame we're going to blur just a little bit it really helps just kind of smooth it out and then finally i want to do the set white posit i want to retain the original curve direction so anytime you use this attribute blur note and you put it on to the p attribute there it's going to start to kind of shrink it and just change the overall shape so i want to go and get the other pause here and that is equal to point one and we want to get the p attribute and a pt num and we just want to set the at p y on the original curve there to the other paws.y and there we go so let me drop down a null node here just kind of make it official just call this out and let's go back here and watch this uh work its magic actually we need the points on so we can see something or you can go and actually let's do this uh let's do a polyframe at the end here and uh do some sweep geometry we'll put in the flow normal and then we'll put in our curve directions there we go and then we'll do a sweet note it just ensures that uh you'll get proper rotations for your sleep node set this to a ribbon and we'll make this something like eight maybe even bigger let's do 15. there we go let's reverse it cool so we got some geometry we can look at it's all these red areas where it's above the 15 degree threshold so let's watch this guy roll pretty cool so you can go and see it's trying to resolve the total threshold for the the slope all right so hopefully you guys enjoyed that those are always fun to put together let me know if you guys have any questions and thanks so much
Info
Channel: Indie-Pixel
Views: 7,385
Rating: undefined out of 5
Keywords: Houdini, Procedural Modeling, Houdini 18
Id: l4Z0X20ikSw
Channel Id: undefined
Length: 30min 18sec (1818 seconds)
Published: Mon Jun 07 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.