 Howdy guys, in this next intro to vex video what we are going to do is we are going to walk through how to generate the surface directions from just a given set of points. And we're going to generate these surface directions based off of the hit points that are detected from some sort of terrain. So you can see here what I have is a terrain that I'm generating with a height field and I've just applied some really simple noise to it. But when we go and we actually change the offset of the noise on that height field you can see that all these surface directions are actually pointing down the slope. And we're also getting the right hand side of the actual direction and we also have the normal information. So what I wanted to do is just walk through it because it's a good like fundamental exercise in using vex and how to pull out information from primitives using the intersect function. Now we've taken a look at the intersection function before but we've never really gone into a great amount of detail and depth into some of the output parameters that it provides. So what I want to do is I want to start this off. I'm going to hide this and I'm going to turn on the grid here really quick over here. And I'm going to create a new geometry node. Okay. I'm just going to call this surface directions video something like that. All right. So what I want to do in here is create that height field just so we have a terrain to snap to. So right off the bat these terrains come out quite large. And I just want a little test area. So I'm just going to make it 50 by 50 and then what I'm going to do is create a height field noise. So I'm just going to start typing out noise and grab that height field noise node. All right. So let's go ahead and take a look. So let's scale this down quite considerably. So I'm going to type in 50 for the amplitude and the element size is going to come in quite a bit as well. And I also want to go back to the height field node itself and just start to mess around with the grid spacing so I get a little bit more resolution. It's just going to give me some more surface to work with. All right. It was a little low-res before. So what I want to do now I'm going to bring down that amplitude even more. I just don't really need all that height. I just want to kind of have a nice little test area here to play with. So with that I think that's pretty good. I'm going to go and convert it to a mesh. I'm going to drop down a convert height field node over here like so. And I think the density is all right. We can maybe pump it up a little bit more. You know. It's not too bad. Just like that. All right. So what we want to do now is create just a really simple grid. So I'm going to drop down a grid and I actually have a preset already set up. And that just basically sets the size to one in both directions and the rows and columns to two. So this is perfect. I'm going to use this grid to scatter points onto. And these points are then going to get snapped to this height field that we just created. Okay. So let's go in here and I'm actually going to make it 10 by 10 in here instead of one by one. All right. If we take a look at the reference, maybe go a little bigger. Let's do something like 30 by 30. And I'll actually copy this first parameter, the X parameter here and put it into the Y just so I can just mess with this one that makes a little more procedural since we are doing procedural stuff here. Okay. So I am going to drop down a scatter node already and this will give me a set of points. So what I'm going to do is just kind of limited. I'm just going to put it down to 100 for now. So in this max points right here, what I'm going to do is set it to 100 and just mess with the global seed there. Just get a different layout. Okay. So this is working out pretty good so far. So what we want to do is now get the snapping working. So I'm going to drop down a wrangle node, an attribute wrangle node, okay. And I'm going to feed the scatter points into that first input right there. Okay. And then I'm going to take the height field and pass that into that second input. That's going to be input index one and this is index zero right there. Okay. So we're going to use both these pieces of data right here to perform the snapping and surface direction calculations. Okay. Okay. So the first thing that I want to do inside of this wrangle node is I want to get the points just above the terrain all the way to the top here. All right. So I'm going to come into the vex expression window right here and I'm going to actually hit alt E and that'll bring up the actual script editor they have for vex. So it's just gives me a little bit more room because the script is going to kind of end up being a little long. So all right. So let's get the points sitting just above the terrain there and to do that what I'm going to do is I'm going to declare a new vector and we're going to set this vector variable name to max height and I'm going to use the get bb box max function and pass in input one. Remember input one is our terrain. Okay. This would be input zero. So we're going to get the max bounding box from the terrain itself. So with that information what we could do is we can say at p so that's the position of the current point that we're running over. We're going to set its y position to equal that max height plus a value of one just to nudge it up a little higher. So if I hit apply down here you'll notice that the points and I actually made a mistake I need to put max height dot y there we go hit apply you'll notice now the points are hovering just above the terrain. So this is perfect because I want to basically cast a ray down from each particular point alright and it will then detect whether or not it's going to hit that surface so we need them above the terrain right there. Okay. So that is good. So we should always utilize comments as much as possible alright so what I'm going to do is just say set points above terrain alright. So then what we're going to do is we're going to intersect the terrain and snap alright alright so to do this what we're going to do is we are going to create our output variable so our first output variable is going to be the hit position so if we do in fact get a hit so we're going to store it into this hit position variable and then we also need the vector called ouch uvw alright and that's just the name I'm coming up with okay but we're going to store basically the uv information uv position that we hit at and we gather that from the primitive that we hit and we can actually use that to derive what the normal is for the current point based off of what the normal is on the primitive so let's take a look and see how all this works. So to do the intersection what I'm going to do is type out int hit is equal to intersect alright and we're going to intersect with geometry one or input one that's the terrain okay so that's why I'm putting a one in there and then if we actually go to the help for this alright so if I hover my mouse over the intersect function here and hit f1 on the keyboard it will take me directly to the intersect function over here so we want the origin alright so that's just going to be at P that's the position of the current point that we're working on it wants a direction vector alright so what I'm going to do is just set this something really large I'm just going to say a negative 500 and zero alright and then we want to output the position and the uvw so we're actually using this particular override right here so I'm going to do another comma and we're going to say hit pause goes into that first argument there and then out uvw goes into that second cool so now we're getting the position and the uv information about where the point was hit from the raycast onto the terrain so now what we're going to do is we're going to say if hit is greater than or equal to zero alright and the reason why that works is because the intersect function is going to return the id alright the prim num basically of the primitive that we hit alright that's an integer value so if we were to actually visualize this here and in the editor so if I turn on my prim numbers alright and actually we'll switch over to the terrain for this particular one every primitive in here has an id that's that prim num alright so that's what's going to be output into this particular hit integer okay so if it's greater than or equal to zero alright then we've hit something because the last or the first I guess you should say primitive is primitive zero if it's negative one then we didn't hit anything alright let's turn off those prim nums and let's go back to our attribute wrangle right here just template the terrain again alright and let's go and say well if we hit something then our position this is the easy one is equal to hit pause alright so that'll get all the points actually snapped to the surface voila very nice okay and what I want to do now though is I want to extract the primitive normal okay that the point actually hit and I want to assign that normal direction to the point so now we can generate a normal for a particular point okay so in order to do that what I'm going to do is declare a new variable called the wanted normal and this is going to be equal to the prim uv function now we haven't seen this one before and what we are going to do is quickly take a look at the help for this okay so the prim uv vex function returns the position using intrinsic primitive UVs alright this is what we want because what we're getting is UV information from our terrain that we're hitting okay and to use this what we need to do is give it a geometry so we're going to look at the terrain geometry so we need to put one in there that's the second input that's the input that we're putting the geometry into the terrain geometry we need the attribute name so we're looking for the normal so that attribute name is n okay and then the primitive number and again like I said this hit variable is storing that primitive that we hit so that's the that's the prim num and then we want to use the out UVs alright that's the position that we want to sample from alright so that's how that prim UV function works so this is going to return for us that normal and you can pull out any attribute using this particular information alright you just need to change this attribute name okay finally what we can do is we can say at n is equal to that wanted normal and with that we will get normals for our particular points and they're completely perpendicular to the actual surface of the terrain so what we want to do now that we got all of that working I should spell this correctly as well what we want to do now is just build the surface directions for all of these guys alright and so what we're looking for is the right direction and the forward direction so we have the y direction basically so what I want to do is build the surface directions like so and this is actually quite simple but the first step to do this is to flatten out the actual y normal so what we want to do is we want to say that vector flat norm is equal to at n first off okay and then we're going to say the flat norm dot y is equal to 0 and then we need to normalize it so we're going to say flat norm is equal to normalize flat norm easy peasy alright so then if we visualize that by assigning the normal to flat norm or assigning flat norm to the normal what we want to do is do that apply it and you can see that we have the normal now that is pointing in the slope of the actual terrain so this is very useful information for us alright so I'm going to get rid of that what we want to do now is build two new vectors so the right and the forward okay so the right is easy enough we're going to do v at right so we're making attribute that actually sits on the points alright this is in a local variable okay and we're going to do the cross product of the flat norm alright with the complete world normal alright so the y direction or the up direction world space alright if we hit apply alright and accept that what we can do is actually visualize this with the visualize node so let's get the visualize node out here okay and what I'm going to do is go into the visualizers area here and we're going to call this right and right for those two and I'm going to set this to a marker okay and I'm going to set that to a vector and then a sign for the attribute assign that right attribute that we just created and you can see now that we actually have that perpendicular right direction and what I need to do or what I want to do is give it that red color usually that's indicated indicating that it's the right direction okay so let's go back and let's actually name this node to write just so we know what it's doing and let's open up our text editor or a script editor here using alt E and let's create that other forward direction so I'm just going to abbreviate that with FWD and we're going to do the cross product of the normal so the actual up direction on the point so the normal and the right direction and this will give us that forward direction so let's hit apply and accept and so what I'm going to do is I'm going to create another visualize node by holding down alt just hold it down and then drag the right no doubt and create a copy of that just so we don't have to you know type in too much stuff up here and I'm going to call this the forward and so we can rename this really quickly and we're going to give it the forward attribute and then I'm going to go and give it that blue vector and with that we have completed our surface direction so now we have a complete directionality so we have a bunch of vectors that are defining you know how this particular point is facing down the slope we have the right direction and the up direction so you can use all that information to do quite a bit of things and if we move the surface at all all right so we come back up to this noise up here and we change the offset you can see that the points themselves are reorienting themselves to their new slopes so very useful information all right so I'm going to close out the lecture there the video there and in the next couple of videos we're going to cover you know a couple more cool features we're going to do some more searching algorithms and I'm going to get into more like plotting functions stuff that's really useful when you're doing procedural modeling okay thanks so much