Houdini Games Workshop - Advanced Road Editing using Houdini & SideFX Labs

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello everyone and welcome to this workshop about advanced road editing using houdini and side effects labs my name is erwin hymes and i'm a technical artist at ubisoft for the past nine years and i've worked on multiple titles including ghost week on wildlands ghost week on breakpoint and most recently writer's republic and next to that i'm also a houdini teacher and consultant and i've been teaching houdini for the past six years or so now over the past year i released my first free course out on my youtube channel eodine academy it's basically the introduction module and the foundation module which teaches beginners how to use houdini next to that i'm also a procedural r d consultant and currently i'm working on pipeline and world building with an architectural company okay so let's talk about what this workshop is going to be about so over the course of this presentation i'm going to cover how procedural road networks are constructed we'll have a quick look at the road pipelines of ghostweek and wildlands and what i've learned by studying the unreal engine 5 city sample demo and then we'll cover the new tools that i've developed for side effects labs and how they can help you among other things to build and manage road networks with houdini so first i'd like to have an overview about how roads are built and i'd like to start using ghostweek on wildlands as an example let's have a look at the roads that were generated in ghostweek and wildland and how they were constructed for a project of this scale so for ghost week on wildlands my focus was on the road building tool and it allowed us to produce procedurally over 600 kilometers of roads at various sizes material styles and also included road propsing and terraforming for the entire world now over here on the right we have the terrain as it was originally and then we have the roads stamped into it and the way this worked is that we had a pathfinding system that would find a path across the terrain from point a to b and it would then do all the processes after that to stamp it into the terrain so if we look at it from this point of view our terrain was divided into 64 two by two kilometer tiles each of these tiles had a generated pathfinding grid we could then connect together these waypoints into a larger lattice that would eventually form the basic connections of our road network the pathfinder would path over these connections and then output the roads that would then be terraformed into the terrain so over here i have an example of the road pathfinder in action we have points a and b and then it will pathfind between those creating switchback turns if it has to go up a steep slope but in general the pathfinder here tries to find the shortest path possible while making the least amount of turns though how many turns it makes is configurable then we would combine these together we had railroads we had large medium and small roads and then we had villages and if you combine that all together then you get quite an extensive road network that had to be managed and maintained over a long period of time during development of the game so the way how this was done was using a road generator tool now version one basically worked like this here we had our two by two kilometer tile and then we could place waypoints on that tile to go from point a to b like so we could also place guides if you will for bridges and later tunnels and then if the pathfinder would try to path between this point and that point then it would basically follow this connection here creating a bridge and then finally we could draw an exclusion curve which would prevent the pathfinder from going through this area so we'd have to find a way around so if these connections defined we can then run them to the pathfinder system and this will produce these raw curves now these are too rough to produce final roads so first we have to clean them so we do a smoothing pass we also take any intersections and flatten them this is better for the vehicle traffic in the game i would take any switchback turn or sharp turn in a hilly environment or on a slope and i would widen it out give more space for the cars to traverse and then finally we can create a ribbon from that and prepare a terraforming stamp so the first thing i would do is export out this result here to a road curve network and then also run this through a terraforming stamp which we can then turn into terraforming textures one for each tile of the world map so it's easy to composite together speaking of compositing here is the road system so on the left we have the input tools then we had the grid and the connections and how they would pathfind across the world this would then be combined together into a larger network of roads for the entire world we would run the terraformer through that for every tile and that would then be run through the compositor to be stamped into the terrain now this tool set worked but it had its downsides mainly that the pathfinder could be unpredictable and we had the issue that roads could shift so as a second version of this tool i changed it around a bit basically i took the pathfinding grid system and i moved it to the front so we first have the grid for every tile in the world then i combined all of these editing tools into one tool and i turn that into an editor meaning that we save the result to a cache and i also perform the path finding whenever i draw a road so the pathfinding is now inside the editing tool this basically meant that we had immediate results from the editing tool that we could then also immediately push into the game engine so here's a little demonstration of this version 2 of the road builder this is basically an editor meaning that we have a road here in the world but we also have it in houdini because i'm using a cache i can see it both in the game engine and in houdini at the same time i just have to refresh the tool now what i can do is i can add remove or update roads and i can set their settings as well so the type of road and its size i can then draw waypoints and move around my waypoints until i'm happy with the path and then save it to a cache if i don't like something i can also remove it so here i can draw two points and specify i want this section to be removed and then draw a new part in between or i can specify this section of the row needs to be changed to a different type and then maybe add some more roads as well now once this is all done and i'm happy with the result i can then run it through the render farm and get the result back and in about 30 seconds to a minute i would have the final road network or at least i would have a preview that i can then preview in the world in the game and then i can bake it to the final terraforming now in this case i was editing the roads in houdini i could also edit them in the game engine but if i were to edit them in houdini i would need to also be able to see where they are in the world and for that i could use this road viewer this basically viewed the um cache and it also allowed me to test a couple of other things like dead ends and find out if there were any disconnections basically if there was a disconnection or an end of a road it would indicate it with a giant cone bridges were blue and then we had different road types as well as the railroads that's a pretty quick and easy way to see where your road network is now those road curves had to be clean because otherwise a lot of other systems wouldn't work properly they relied on the road network to be cohesive and this was important because we used it for a lot of systems like we had bridges and tunnels we had power lines that had to be placed along roads the decals and the markings had to be placed procedurally the vehicle ai of course needed to know where to go and for that they needed a consistent road network the village tools had to connect to them and finally we also had other checks that we could do like prop clearance and the in-game map so a lot of systems relied on a clean and properly managed network of roads now as for villages basically they hooked into the main road network they would flow from a town center outwards but then in the end they will be added to the road network as well and since villages had a lot of ai activity and ai paths in them also footpaths for npc traffic all of this had to be managed procedurally and connected together so as we added more content to the game we had a consistent and functional road network all throughout that was very important finally we also had cities and these got quite extensive and these included rural roads like the ones you saw before we also had these grid patterns in the center of town we had sidewalks that npc traffic had to go over and footpaths in between that connected to the houses like in the backyards so a lot of pathing a lot of little connected paths that had to all make sense so we go from this to that basically a complete town with full ai vehicle traffic going through it and everything the only thing we might have to do after the procedural pass was do an art pass okay so let's move on to the next topic i would first like to talk about how we can take procedural roads and break them down into their most core components so what do we actually need in order to build procedural roads now over here i have the city sample for unreal you can get it for free from the epic game store and it uses houdini to construct the entire city with malt kits that includes the streets as well the streets themselves are made by combining mod kits together so that means the network has to be quite clean and it has to be predictable now if you want to look at this for yourself you can find it with the city sample so you can look for the houdini files in there now over here we have a typical intersection in this city environment and you can just imagine that there are lines running along the roads like so and then if they intersect we have an intersection point okay so this is where the lines are connected we can then break it down even further by cutting the intersections into these roads as well the intersections themselves scale depending on the road width and the angles of the intersection so they need to provide enough space at the end to properly create sidewalks because otherwise they won't have the space to exist plus it creates a nice space for the stop area where cars would wait it's quite useful actually so here we can look at it from above and we have again a road network here of connections and intersections and then here on the left we have a couple of green dots and these are basically corners so in the unreal city sample road segments are always straight and that means that any turn is basically treated like an intersection with only two exits but these don't need any stop areas like there and then if we look at the intersections again you can see how the intersections reserve some space on the roads around them but then in between we have these straight segments that are basically just one section of road it has a width that width does not change and it has a certain amount of lanes and a style okay so since this is generated in houdini we can look at the files and check how they are constructed under the hood so over here we have the proxy geometry basically the roads but also the highways or the overpass and the proxy buildings now if we have a closer look at that and we ignore the highways for a moment then here we have the proxy mesh for the road network like i said the roads in this project are created for mod kits and these are basically all the models combined but if we look at it even deeper then we can see that all the sections in between the intersections are basically just lines with a width and maybe a row type value and then if we look even further this is basically the network of roads that you get at the very beginning of the tool after this network is constructed but before intersections or mod pieces are placed in position and with this i'm basically trying to prove my point having a clean road network of curves is very important and the way how data on those curves is carried like in this case the road with is also important we don't want the mess of that data however the unreal city sample is a procedural tool and generates the entire city from scratch from the road network here up until the buildings from start to end meaning that we don't have to worry about users drawing roads that maybe won't work with our city but the moment we need to make something that needs to be editable it gets more complicated so here is something that i've been working on this is a tool that i'm currently developing for an architectural company called emerza and i'd like to thank them for giving me permission to demonstrate a part of this tool for the workshop because i think it will help me prove my point so this here is basically a road mesh and it constructed from a couple of different key elements so first we have the intersections now these are quite complex to build and if you don't limit what kind of intersections and angles you can create like they did in the unreal city sample it gets quite complicated however in their simplest form they simply require enough space to round a corner and they need to support the width of the roads that go into the intersection on all sides now in between we can create these fillets or basically a connection that goes from one end to the other and then we fill it up with some geometry inside of the intersection square now i'm not going to focus on this today but you can see here that intersections with different roads at different angles can get quite complicated and these are still simple intersections because they only have three or four exits they can get way more complicated real quick if you're not careful now next we have the road segments in between and in this case they can round corners so at the very least i need to make sure that the corners of these roads have enough radius in order to allow the coordinates to exist properly especially when the roads get bigger when they get wider right now you can also notice that we have a couple of side roads in here these don't create intersections instead they connect directly to the sides of a bigger road like the orange one does here with the blue road now in order to construct the roads from these lines over here we need to have a couple of variables for example we need to know the road with right each road has a certain width and we need to store that and i prefer to store them on the primitives because the primitives themselves describe the entire section of a road segment if we were to store it on the points instead it could cause problems when we start combining roads or cutting them i'd prefer to store it on primitives but we also might want to store other variables on them such as the speed limit which might differ depending on the environment that the road is in and of course if we want to store a road name then that's going to be different for every road in general right other attributes we wanted to store are elevation angle and road grade and these need to be included for um say if you don't want certain elements to be spawned on a steep road um if you want to know where corners are or just in general know how high a road is and all of this data needs to be maintained if you want to work with your road network if you edit it these attributes need to be kept now other information we can store are groups so we can for example here group intersections we could group every intersection with a single group or we can maybe differentiate between these types of intersections with side roads and then the bigger main intersections as well and then finally we have road direction now the store road direction we could use a point vector attribute on the points of this road that would aim along the road direction but this will have to be constantly recomputed every time we change the curves and this risks the curves being corrupted if you will so the thing is polyline primitives already have a direction in their vertex order so if we look at these lines themselves you can see that their vertex order will follow along the direction of the curve each primitive starts at vertex 0 and ends on how many points it has so in this case we could say this line here has 11 points so it starts at 0 and it ends at 10 right however working with vertex order isn't the most intuitive thing in houdini because there is no way to view the curve directions by default you can only do it by looking at the vertex numbers here and also some tools degrade your curve direction like it's easy to flip a curve around if you start doing operations on it so we need to know what the curve direction is and we need to be able to edit it safely now for that i've been making a couple of tools and i'll be sharing those with you right here in this workshop they're now part of the labs toolkit so for the labs toolkit i've developed three new soft nodes which include the labs poly scalpel the merge splines node and the view vertex order node now these three nodes together are useful because they allow us to cut polylines and surfaces and then merge polylines back together which is great for roads because it means we can cut them where we want them merge them back together the way we want them and we maintain all of our attributes our groups and our vertex order as well which is not something that the default nodes in houdini can really do so what i mean with that is there is no simple way to edit curves in houdini there are a lot of node dedicated editing curves but they all have some kind of downside or some kind of thing you have to keep in mind for example the convert line and polypath node can be very useful if you want to segment or recombine a curve however they redraw the primitive and this means that they will destroy primitive groups and primitive attributes when they are run so you always have to export those attributes to say the points and then re-export it back to the primitives after you do these operations next to that the carve node will disconnect all points when it segments things unlike the convert line node but it does maintain primitive attributes so there's a trade-off there right you have two nodes that basically do the same thing but there's something that doesn't quite work the way we want it next to that the poly cut can cut on points but unfortunately when it does it tends to destroy point groups so if you cut a point on a point group usually that point group only gets moved to one of the two points one of the two ends where the cut was made not both and then next the resample node can resample your curves but when it does so it also redistributes the attributes and also point groups in between so often times when you store data on points in a curve and you run into a resample your attributes get blended and that's not something we always want to do right so it's actually really useful to store it on primitives but these other nodes tend to destroy primitive groups so yeah you can easily see how this gets complicated right there's no straight way through editing a curve and then next when it comes to cutting curves so not just using a poly cut on a point to cut at that point but maybe we actually want to inject a new point on an edge where there's no point right so there is no easy way to take a point and place it on top of a surface and then just inject it into say the edges of that surface there's no standalone node that does it for us similarly slicing surfaces with curves is not easily done we can also often not preserve our edge groups edge groups are kind of like a third-rate citizen in houdini lots of nodes do use edge groups however they're easily destroyed and then finally we have the vertex order or the curve direction and like i said there's no easy way to view that so with the labs tool set i've included a couple of different nodes the first one is the labs polyscalpel and this node basically allows us to slice new polygonal edges or points into the source geometry with a secondary cutting geometry and we can do this in various configurations we can do it with points we can do it with edges we can do it with surfaces next to that it also keeps all the attributes and groups intact and it will propagate them through the cutting operation we can cusp the geometry and it will also allow it to deal with coincident faces depending on the method inside the tool that we use next i also have the labs merge splines node and this one allows us to merge disconnected polylines together like the poly path soap cutting them at intersections but with specific conditions now this one actually keeps your primitive groups and attributes intact as well as the vertex attributes and the vertex order and then finally this one's called the view vertex order and it basically just visualizes the direction of each curve and it will create a arrow it will place it in the center of all the points on the curve and it's basically a standalone component from the merge splines node so you can use this anywhere and quickly visualize your curve direction okay so now let's dive into the example files and let's first have a look at the example files for the polyscalpel okay so over here we have the example file for the polyscalpel node and over here i have two geometry nodes the top one has some examples of different types of cutting where we use different methods using the polyscalpel to cut our geometry and get different results it highlights how we can use the tool then down below i have some additional examples on how we can cut geometry and how it compares to the existing types of cutting present within houdini so let's have a quick look at that and the different functions of the node and then let's dive into the main examples i invite you to have a look through these files they should be included with the polyscalpel in the labs toolkit now the polyscalpel node is a multi-purpose node that can be used to cut new edges and points into geometry based on its different modes right now for example i am cutting a polygon surface using a polygon surface and i'm using the polysplit method this means that i'm basically using the polysplit node over here but it's constrained in such a way that it can run in a loop and it is a lot more reliable than as a simple node next that we can also use the boolean method this one is faster because unfortunately the polysplit is not the most performant node and depending on which mode you use you do inherit some of the limitations as you can see here but overall these nodes are able to work we can cut this geometry so in this case i'm cutting a surface with a surface if i move this around then you can see how the cut moves along with the cutting surface next to that it does also work with coincident faces or overlapping geometry in this case i have these two boxes overlapping exactly and in this case i'm cutting the first box with the second box but only with its edges so in this case i've set it to polyline mode not polygon surface mode and this allows me to take the edges of the second box and even though they're overlapping exactly on the other geometry it will allow it to make a cut and as you can see from the primitive numbers this is reliable okay so next let's try to cut a box using just edges so instead of using the edges from this geometry let's just create a couple of curves so in this case we have a couple of curves here that are overlapping our box and based on their proximity they will either cut into the geometry new edges or they will add new points so as you can see these overlap perfectly and this one here is a just approximate to the mesh so if i move this one it may or may not make a cut this is pretty useful because it allows you to create precision cuts along your geometry in whatever way you want to now it is important that your cuts actually meet the edges of a surface if they are near the surface it will try to autocomplete and if we want to instead of slicing the surface we can also decide to only inject points into the surface wherever our cuts cross an existing edge so if we switch this to points on edges mode and we look at the point groups you can see that here we have some cuts that were made moving on here we have a plane and we can cut it with another plane and in general if we have a high enough snapping value likes let's say a value of one and i move this close enough to the other edge it will snap and complete the cut it is important that you set the snapping value correctly if you set it too high it may oversnap now this snapping feature is only enabled when we are in poly split mode in boolean mode which is the other mode of the tool we don't have this behavior and in this case we do need to make a complete cut in this case the geometry has to either be exactly on top or overlap but in polysplit mode we do have the ability to auto complete our cuts even if they are partial so in this case you can see that it makes the cut just fine now at the moment the tool is in auto precision correction mode and this basically means that it will try to look at the geometry its size and the size of your cutting geometry and create a reasonable snapping value this is useful to make sure that the polysplit method doesn't over snap if we turn this off however then now it will no longer make a proper cut and this is because it's collapsed or cut into the existing edges of the geometry so basically if you set the snapping value too high it may oversnap and cause undesired results so you can control this and set it low enough so that it works or ensure you have auto precision correction enabled follow these instructions up here and you should get a reliable cut which is useful if you want to use the tool procedurally and the rest of these examples basically demonstrate that we are able to cut our geometry using edges as well so over here i am cutting a surface with an edge and that works just fine or i can use a point so in this case i can take a point on an existing edge or near an existing edge and then if i set the tool into polylines or cut with points because these are polylines i'm now injecting a point into this edge and dividing it into two primitives if i switch it over to a solid piece of geometry like this one i switch the tool into cutting polygon surfaces with points and then look at the result again we've injected a point into this edge and added another point into the geometry which is not a feature that houdini has by default so there's a basic overview of what the tool's capable of there are more features here as well but if i go over everything this would take too long let's instead have a quick look at the practical examples and what we could potentially do with it okay so let's quickly have a look at a couple of examples on how we can actually use the polyscalpel node in different configurations so let's have a look at this one here so this example actually demonstrates how we can cut a complex surface using a couple of simple shapes we start off with a floor plan and then i have some corridors that are overlapping that these are two meshes they are basically pulley curves right i overlap them and i set the tool into cross-cutting mode and cross cutting mode allows me to cut using a hull from the original geometry basically in the cross direction of the geometry itself and it will then cut the other geometry with that we are currently in boolean shadow mode meaning that it is cutting using a faster method but we can also cut using the polysplit method if we want now this will inject new points and edges into the geometry and also subdivide our geometry into different primitives let's group the central corridor here this central primitive and i do need to make sure that i have the right one selected right and then let's feed it into the next one so in this case i have some edges here and these edges are overlapping our geometry but i have told the tool that it should exclude the corridor group we made over here meaning that it will now cut into this geometry but it won't cut the corridors so here we have a couple of lines that describe say for example the edges of a room or the walls of a room right now the tool itself has snapping features enabled so even though my edges themselves don't perfectly overlap the geometry they do snap and we can use that to our advantage for example if i move this point then it will try to auto complete and create a cut like that there can be pretty useful then next let's say we want to add some points into these edges for places where support pillars should be located well if we were to grab a couple of points that are near the exiting edges of our geometry we can then feed them to this poly scalpel which is configured into polygon surfaces cut with points we have a snapping distance which is visualized by this guide here and then it will inject it into the edge we are using this group however to exclude one of the points from our cut so we're only cutting these points here and then finally i would like to add some doors now let's say these boxes here they represent the the space where a door should go well i have them overlapping the edges let's use the cutting mode points on edges only and this will allow me to inject new points where this box intersects the edge but it won't actually cut the shape of the box into the surface which it would do by default it only cuts the edge so with that if we then feed it through say a little procedural process we can create a couple of walls out of it and like create a little floor layout basically now there's something that you might have noticed and that's that we have some edge groups over here and throughout the entire cutting process these were maintained so for example we created this first cut over here and created this edge group throughout the cutting process this edge group has been maintained and the same thing is true for a primitive group and my point groups and if we had attributes on here those would have been maintained as well so in other words the tool maintains your groups and your attributes throughout the cutting process so if we have say for example a couple of uvs on our geometry regardless of the cut they are maintained the same thing is true if we have some other attributes like in this case we have some attributes set up here and throughout the cutting process they are redistributed depending on what type of cut we made depending on what type of attribute it is but they are maintained like in this case for example this group here was maintained even though this box has been cut so having the ability to maintain attributes in groups means that we can make cuts without having to worry about our existing information being deleted and finally as i mentioned we are also able to cut polygon edges or polylines with any of the existing methods so surfaces edges or points so in this case i have a simple curve object and i am cutting it with a plane and i've also for fun animated that plane so here you can see we're injecting new points into the curves we're also gusping this geometry using cusp cut points and when we do that that means that we can explode the mesh maybe add some geometry where our cutting groups are our point groups and there we go we have a nice little animation using the tool so yeah we have a lot of options here i invite you guys to look through this in the workshop and then let's move on to the next tool which is the merge spline node because now that we know how we can cut geometry let's look at how we can put it back together which is especially useful for road curves alright so next let's go over to the merge splines node and also the view vertex order node and let's check out those examples but first let me introduce you to how this tool came to be so originally a few months ago maybe a year i started working with a mentor student in my e-houdini academy mentor program and he wanted to create a race track and he needed to manage a lot of different roads now for that we started working together on this little tool i explained to him how we could make editors and how we could combine roads together but it quickly became apparent that these roads were very complex and he needed something more thorough so that's where the merged splines node was born out of now what you see here is the final result he managed to turn this into a racetrack generator now he made this on his own for a company called aminica brands after we completed our mentor sessions and it was able to create a very thorough race track with side roads parking lots main roads and the main connections between those roads were all managed by an early version of the merge spline salt but basically this is what the road network looked like when he was done with this racetrack and here you can see the node in action okay so here again we have the example file in this case for the merge splines node and i have several examples laid out here so you can see how you can use it let's first have a look at the node itself and what the icons here on the screen indicate to the user so the node actually has several functions but its main function is to take curves such as these and combine them together based on criteria or merge conditions and then also manage the attributes that come with them so in this case i have several curves here that are supposed to be merged these two need to be connected and these are already connected now if i run that through the merge blank node you will notice that it starts showing several different icons on it the icons indicate different types of merging behavior or the state of certain curves so for example here you can see whenever you have a blue sphere it means two points were fused but there was nothing to merge if it's a green sphere they were fused and they were merged meaning that this primitive and that primitive were combined together if it's an orange sphere it means they were already fused but they were merged because they were already connected but they were two separate primitives that could be combined into one next that we have these arrows the arrows indicate the curve direction or the vertex order of this part of the spline and they will be visible on the center of each spline now the smaller arrows indicate the curved direction of the original curves so the original curves before this curve was merged into one curve and finally we also have these little red arrows you can see and those indicate the end of a curve or if there was no merge made so basically if nothing else connects to the endpoint of these splines so now that we have an idea about what the tool does let's look at the individual functions one by one and then see what we can do with a more complex road network over here i have an example which i'll go to in a moment where i have a series of curves i can clean them and then i can edit them or recombine them basically as a means to inject certain elements like these round corners and i can do that really easily while maintaining all of my attributes and groups now to do that you need to understand how the tool works so let's first dive into these examples here and have a look at that over here i have an example about how primitives can be merged so let's take this one here have two lines and these lines come with a couple of attributes first we have the primitive string attribute here which has abc or this string on the left and def on the right we also have the color which in this case is a primitive color and of course we have the vertex direction which is inherent to these curves now i'm viewing the vertex direction using this view vertex order sop which is the other labs node that i've included but if we want to merge these splines normally if we were to use a poly path sop we wouldn't have a lot of control over which curve and its attributes are used now with the merge spline stop this is quite easy all we have to do is feed these curves to the merge splines node and assuming they can connect they will merge together and all the attributes from one of the curves will be used for the entire curve so in this case i have snapped it using a snapping value up here if i lower this notice how the curves don't snap and if i increase the value you'll notice how the curves will start merging now if i set the value too high the curves will start snapping to themselves and then you won't get a good result so if you want to you can also specify that it should only snap the end points or any endpoints and intersections so if that even if our snapping value is very high it will still merge the curve into one now the way how it grabs the attributes from one of our two curves here is determined by the primitive merge behavior we can specify that on the node over here so right now it's grabbing the attributes that is the attribute abc and the color and it's grabbing it from the lowest primitive number we can also make it grab it from the highest primitive number in which case it gets grabbed from the second curve this one now if we want to separately change the vertex order let's say we want to grab the attributes but not the vertex order we want to keep it going this way to the right then we can also specify that separately over here right now it's matching this parameter but we can also specify it separately so let's say we use the attribute over here and use its alphabetical order to determine which vertex order it should grab if i set this to by attribute first value and then i specify it to the primitive string then now you can see that since the primitive string on the left was abc and on the right was def it grabs it from this curve but the merge behavior still tells it to grab the attributes from the second curve and just like the vertex order we can also use attributes to drive the attribute promotion as well so over here i have a weight value on the blue line of four and on the red line i have a weight value of one so if i set this node to use the attribute by first value the lowest value and i use the primitive weight and now it will grab the attribute value from the left curve based on this weight value here not only primitive order so if i drop the sort node in here and i flip it around then now even though the curves have a different primitive order it still grabs the attributes from the curve on the left because of its attribute being the lowest okay so let's move on because besides being able to merge attributes from primitives we are also able to merge point attributes as well so over here i have an example where i have three curves and these curves have a couple of values so they have this string value here a b and c they have point weights and they also have primitive weights and we can merge these attributes whenever points are fused together based on those attributes so over here i am merging them based on a primitive weight and it's grabbing the last value so if i look at that i look at the primitive weight it will grab it from the blue curve and when i look at how the points were merged here you can see attribute b was kept now this one is using a primitive attribute we can also use a point attribute as well so in this case we are using a point attribute to drive the promotion method if we look at the weights you can see that the highest value on our point attributes is 5 and when the curves are merged it will grab the attribute from this curve because right now this point attribute is set to use the last value if i use the first value it will use the blue line because the blue line has a value of 2 over 3 and 5. and with this we can have different types of merging behavior we can use the point order or we can use for example the sum of all the points together and return that value so in this case that would be 1 2 and 3 becomes 6. so yeah basic promotion systems all built into the tool now next over here we have the snapping behavior in this case we can determine how points should snap i have two curves and depending on which one i use it will snap to a different location in this case they're snapping to their average position we can also snap by point number or by an attribute value or in this case we can snap by a target group so the points will always snap to that point if they are merged now if we want to merge a couple of curves but not everything like in this case for instance we can use a fuse filter and only fuse points that were selected in this case these two points were selected so when i fuse those it will only combine these and leave this curve alone likewise we can also use this by attribute so i can tell it to only snap curves together that share the same attribute in this case this one has abc and this one has def and only these two because they have matching attributes can merge so this is also again very useful if you want to make sure only certain curves are merged together and then finally let's have a look at how we can use that filter to limit our operations and only affect curves we actually want to adjust and when i go to the final example for the roads this is very useful so over here i have several curves and they're all being combined together at least as long as they are within this filter here they can snap these two cannot so they are kept apart but because these were already connected they are also merged into one curve you can see there used to be two curves now that one now in case i only want the merge points that are in my selection like in this case for example where i have a group selection on this point and i only want to merge those i can turn on only merge on fuse filter selection when i do that only these two curves are merged and these are left alone they won't be processed and they won't be altered in any way so this is pretty useful if you want to limit your operations to only a certain set of your primitives now in another case like this one i have only combined these two curves and these two based on a shared attribute so right now these have the attribute abc and these have def these could also be numbers they're not limited to strings and if these attributes match then it will merge them now if i disable these options it will merge everything into one because of the snapping distance so we have a lot of control over this now i mentioned that we can use a fuse filter let's get this example over here where i have a very large network of connections and if i want to merge these it's actually quite heavy because i'm running a lot of operations at once if this were a road network or a maze like in this case it would take quite a lot of time to merge these together now let's say we want to make this run a bit faster we can what we can do is we can create a group for say um all our points that have two connections so no intersections but only straight pieces of curve that consist out of separate primitives well we can group those and then we can run them through a merged blind salt with a simple fuse filter selection we can then run fusing operations only on specific parts of our geometry and by doing this we are only executing this operation on a subset of our geometry the rest is left alone and this is a lot faster which is useful if you want to only connect very specific parts of your network together but leave the rest of your network completely untouched in some cases that's necessary and this facilitates that so now that we've had a deeper look at the merge splines node and the polyscalpel let's see how we can use them in practice when we want to edit a couple of roads over here i have the workshop example file in this i have two examples one for cleaning road curves and one for creating a road mesh from those curves and combining different sets of meshes together so you get one single coherent mesh now there are different ways to create roads this is just one of them but you can take some of the practices from this example and use it for yourself now let's get started first i would like to say that these examples especially example 2 are partially facilitated by imaza which allowed me to use part of my road builder i made for them now let's have a look here first we have this road network here let me change the color and these are a series of curves that form a road network but as you can see they aren't completely clean first some of these curves are disconnected and are actually facing in the opposite direction from one another even though this is arguably a single road next some other curves span multiple intersections and aren't cut properly and this one does share the same direction but is cut in the middle so we want to clean this now it is important that these curves do meet on their points and i also have a couple of groups in them but i'm not going to use those right now okay so first let's see what we can do with this problem here and also clean the other issues that i just mentioned so what i would like to do is take the curve that's the longest in this case and take its vertex order so in this situation this curve's vertex order is used and overtakes this one we can do that by measuring the perimeter of this edge and if we were to visualize that plug that in we can say perimeter and then you can see that this one has the largest perimeter of about 400 meters and this one's 200 meters so if we sort by that then now this one will be the highest primitive number and that one will be the lowest so let's run that through the merge spline node here what i'm going to do is tell it to use the vertex order by the last value for the perimeter and when we do that it's going to use this curve and overtake its direction and combine it right there next to that some of these other curves that were disconnected before are now combined so here's one and all the segments on these curves here are now segmented by their intersections because this node is being run on the entire geometry all at once all the intersections will be cleaned at the same time you'll notice that we do have some guides indicating that some points were snapped or fused and that's because they were also disconnected so now we have a fully recombined road network that has been cleaned and we can proceed then down here i have two examples so let's say we're going to edit our road network and we need to post-process it to make sure it still makes sense after we're done editing it so let's remove a couple of these uh curves here now as a result over here we have a single road which consists out of two separate segments with two separate values and curved directions if i visualize my road width for example you can see that this is a road of 35 meters wide and this one is 20. now the problem with that is that if we want to support that in our road builders we need to make sure that our roads can transition from one road size and one road style into another without joining at an intersection that might be a problem so we have to keep that in mind or we have to fix it now we can fix that quite easily by using a merge blind node we can plug it in and if we merge the primitive attributes and vertex order by the last value in the road with then the largest road will always overtake any smaller roads that are merged together so we can use that to clean this up as you can see we now have one segment here with one curved direction and one size now in case we do want to use these as separate curves we can do that we can specify that we only want primitives that have the same value to merge so if we set our road width over here then now it will only merge these curves up here but leave these alone because these don't have the same road with so they cannot merge so we have control over this and depending on your needs depending on what your road tools are supposed to do and what they can support you can configure the tool appropriately okay so we can easily use the merge spline swap to clean curves that connect and have different attributes but let's say we want to cut some of these curves and then inject new segments in between and when we do that we still need to make sure that we recombine them to valid road curves so over here i have a situation where i have a couple of very sharp angles because i've removed this curve here now if we were to try and sweep these and i can demonstrate that let's go down here grab our sweep node let's plug that in and i'm going to add a merchant's blind soap to fix these lines up make them continuous if i sweep that you'll see that we do have some corners here but they're so sharp that the geometry self intersects and in general this wouldn't make a very good road turn right now if we don't use the merge spline sub in this case they will be disconnected and we wouldn't even have a continuous road segment so we do need to fix this what i would like to do is turn it into something more like this where we have a rounded term that works well so to do that what we want to do is first mark off all these sharp angle points so i'm going to show you my point groups and i'm going to use a little expression here to grab any intersections and sharp corners as well so any corner that is sharper than 65 degrees is going to be selected that's based on the curve directions that come out of each point then next let's unique all of the intersections in our network and i'm going to grab my corners here and i'm going to expand their group i'm going to expand it by a couple of steps in this case i'm just going to grab it from this corner outward and move it across the points for about nine steps then let's promote that to an edge group and what that will do is it will turn into an edge group selection and then we can use a poly cut here to cut it out so pretty straightforward on the left we have the original network cut out on the right we have the polycut of course we could use the polyscalpel node specify a couple of points on these curves and then say cut splines with points but this works too right so in this case what i want to do is take these segments that i've cut out and just like i showed you before i want to re-merge them into single segments because we do need to run these through a nurbs operation to then turn them into proper curves so i'm going to re-sample them at a lower resolution run them through a nurbs operation and then re-sample them again that will give us some nicely rounded corners finally let's take the outermost points the ones with only one neighbor and let's group those so now we have that we can recombine everything and now we need to merge these curves back together now these curves do have a vertex order as you can see here and in some cases these will conflict so we need to resolve that we can again use a merge splines node combine it all together but if we run this on the entire network then this might become a bit heavy if this network were 10 times the size it would become a bit slow and we'd be running a lot of unnecessary operations we only really want to inject these corners in here right so instead let's use a fuse filter with a only merge on fuse filter selection mode enabled if we do that then only these turns here are going to be merged and the rest of our network will be left alone and this is a lot faster so if this if we run that through a sweep node then now we'll have some proper curves proper curvature no self intersection and uh they're continuous right we have one direction one attribute everything's clean now in this case you might have noticed that these aren't proper intersections now i haven't included my intersection code in this example but i have provided for example two a couple of the outputs from my bigger row tool and you can see here is a road network and this one has been cleaned then i have some intersection meshes that intersect basically between these lines and they have correct widths based on the road width of each line and then finally i have a couple of fillets these little pieces and these can be used to merge roads together where they meet so eventually we'll get this road network here and for intersections it will look something like that okay so how do we get to this point first here is my road network let's look at just the curves and first i would like to cut these networks where the intersections occur so from the intersections i can extract these edges and these are just polygon edges that describe where the intersection ends and if i run that through this polyscalpel i can cut polylines with polylines and it will cut the roads right there at the intersection then next let's remove the road sections that are inside the intersection by using a xyz dist on the original intersection geometry so we have this shape here if we just run a xyz list from its center position and if that is less than a certain amount and the point on this line is a intersection point which we have grouped using this node then we can mark off that this is a intersection point on a mesh so you can see here this point here is now marked let's promote that up and we promote it to the primitive so now these are marked as being on a mesh and then we can remove them so basically first we've cut our curves and then we removed the section in the middle that was overlapping our intersection moving down i'm just going to run this through a sweep operation we're going to get the orientation the up vector and the side direction of each line and from there we sweep it so now we have a couple of ribbons basically road ribbons but we still have these side roads now these side roads didn't actually generate with their own intersection they can maybe generate intersections with one another but they don't do that with the main roads these are secondary roads and these are primary roads in this case they don't form an intersection so we had nothing to cut it with now we don't want these roads to intersect of course so we need to fix that now to do that first let's use a split node to split our primary roads out from our secondary roads so on the left we have the output with just the secondary road on the right we have our primary roads i'm then going to remove all the edges from our primary roads and only keep the outer shared edges and let's run that through a polyscalpel in this case i'm going to cut polygon surfaces with polygon surfaces and use the crosscut mode and this will give me a cutting shape or cookie cutter basically that will cut this curve right here now let's display the edge groups right here we have a seam so that's now cut these curves and it's also injected points based on the geometry of these roads here so you can see we now have points right there which means that it will match the main road geometry wherever this cut was made then we can simply check again if these sections overlap a road and remove them okay so now that we've cut our side roads and they no longer intersect we can now merge them back together with the main roads but in order to do that properly we need to make sure that the main roads also have points in them that correspond to the side roads otherwise we'll have gaps in our mesh for example here you can see how the side road has been cut based on the main roads points but the main road does not have points based on the side road so we also need to inject some points into the main road to make sure they can connect properly first let's run a couple of fuse operations at a reasonable snapping distance to get rid of any points that might be too close together then i'm going to extract the edge so here i'm going to use a edge group to curve node which is a labs tool i've in this case simply extracted it and then we can run that through a couple of operations to create a cutting shape now with this shape we can overlay it on the main road and inject some points so there we go we now have points that match the side road and that should now work properly if we want to connect them together because now both roads match each other let's do a bit of snapping again transfer some groups and connect them together so there we go as you can see these are properly connected together because the edges indicated by this blue line show that there's no seam in between and then finally i would like to add a fillet in between this little section here i already have that so over here i have the fillet and then if i look at this blast node you can see that we have some points i just want to take the outer corners of this fillet and combine them into the main road so we can just use those use a poly scalpel again and inject those points and then we can merge it all together so yeah as you can see we now have a clean complete road network with no seams and we can use that to grab for example the outer edges create some sidewalks from that or do whatever else you want to do with this road network and with that i just like to say thank you for watching this workshop um if you want to watch more of my tutorial videos feel free to go to my youtube channel at iwodini academy or visit my website at iwodineacademy.com you'll be able to find the links to the master class and the example files for the master class right there and of course if you want to join the eudene academy discord community feel free to join us at this link i have over 300 people on the channel i regularly post progress updates there as well as on my patreon account as well so if you were to back me on patreon you're going to get some benefits from that some people such as the mentoring and student tiers they get guidance on discord and for the rest feel free to check out my patreon channel for other information and of course it helps me create more content such as these tools or more video lectures for the master class so with that we've come to the end of this presentation i just like to thank side effect software for giving me the opportunity to host this workshop and other than that thanks for watching and see you out there have a good one [Music] you
Info
Channel: EHoudiniAcademy
Views: 17,626
Rating: undefined out of 5
Keywords: houdini, houdini basics, houdini for game, houdini lecture, houdini lecture unreal, houdini tutorial, houdini tutorial for unreal engine, houdini tutorial game, how to learn houdini, video game unreal engine, world building tools, Ghost Recon Wildlands Presentation, Procedural Pipelines, SideFX Labs, Houdini labs, Houdini Workshop, Poly Scalpel, Merge Splines, Road Building, Procedural Road Generator, Houdini ue5, Houdini 19.5, Houdini Games Workshop
Id: wxsymcHLAr4
Channel Id: undefined
Length: 73min 7sec (4387 seconds)
Published: Sun Jul 31 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.