Better-Tile-Breakup---Terrain-Shaders---

https://m.youtube.com/watch?v=z3f1bE41daI

Frame at 0.00s

Today, I'm going to show you a more effective method for breaking up terrain texture tiling. Let's go. Alright, so we're in the middle of a series of videos about making terrain materials. If you haven't seen the previous episodes, I've posted the link to the playlist for the whole series in the description down below so you can catch up. One of the major problems that we have to deal with on terrain is this problem of texture tiling. So let's hook up our original shader here. You can see that we've just got the texture repeating over and over again, and it really doesn't look very natural. A couple of episodes back in episode 4, I showed you a simple method for breaking up texture tiling. Let's take a look at that really quick. So this is the subgraph that we created here. And you can see that it does a pretty good job of breaking up the tiling, but we can still see some tiling, especially off here in the distance. It's better than nothing, but it's not as good as it could be. So what I'm going to do today is show you a new method. And this method looks like this. and so what you can see here is we've gotten rid of the texture tiling completely. If I turn this off, you know, you can see this is what it looks like without it and then we can kind of dial it in and you can see that it's slowly just scrambling things up and getting rid of the texture tiling almost completely. And the nice thing about this method is that it costs the same or pretty close to the same as that previous method that I showed you a second ago, but this one is a lot more effective. This one was first created by Inigo Killiz and I'll link his original version on ShaderToy down in the description as well so you can take a look at that. So I'm going to first show you how to do this in Unity and then we'll switch over to Unreal and I'll show you how to make it in Unreal as well. So we're going to start out today just by coming down here and i'll make a new sub graph so i'm going to pick create shader graph sub graph and we're going to call this layer iq tile break and we'll open up this new sub graph and get started so the first thing that we need in here is a couple of texture samples and so i'm just going to copy and paste these in from my other version. So here I'm sampling my textures. I'm just going to open these up so they're not minimized. And one thing that's really important to point out is that I have, if I select these texture samples or samplers, you can see that I have my MIP sampling mode set to gradient. And what that does is it exposes these DDX and DDY inputs. And we're going to use these in a minute, but they're really important for this particular technique because instead of allowing the shader to calculate the MIP level, we actually need to pass in some more explicit coordinates for calculating the MIP level. And we'll get to that in a minute. Okay, the first thing that I'm going to do with these samplers is I'm going to create an input sampler state. So over here on my blackboard, I'll just pick sampler state, and then I'm going to connect up this sampler state to all of my four samplers that I pasted in. So I'll connect it to my two samplers that I'm using for my diffuse or for my color texture, and also connect it to these other two samplers down here that I'm going to be using for my normal occlusion and height textures. And now what we need to do is take these four textures samples and blend them together. So we're just going to create a lerp node and we're going to lerp between these two samplers and we'll copy and paste that and we're going to lerp between these other two samplers here so that we can blend these together. Most of the focus of this tutorial is going to be on creating the UV coordinates for these samplers. And so I just want to kind of get this other part of the shader out of the way here really quickly. These samplers here are going to be sampling our color and smoothness textures. And these samplers here are going to be sampling our normal occlusion and height data. And so once we do that, next we need to unpack our CSNOH. And this is a subgraph that comes with the sample data for Unity. So I'm going to pick unpack CSNOH. And if you don't have this node in your create node menu like I just showed you, What you need to do is come up here under window and pick package management, package manager. And then you need to pick shader graph and then select samples. And then we're going to scroll down here to the bottom and you need to import the terrain shaders sample. And that has this unpack CSNOH node in it. And what this node is doing is it's splitting out the color and smoothness and the normal occlusion and height and outputting them as individual channels. Okay so you can see that doing that just great And then the thing that we need to do here at the end is use a pack material node to take all of these individual channels We're going to pack our color, our normal, our smoothness, our occlusion, and our height. And that's going to pack all of these into one single output port called a material. and that's just kind of for convenience so that we can more easily pass around all of our material parameters with just one wire here. Okay and then the last step that we're going to do here at the end is I'm going to open our graph inspector and we're going to set up our outputs. So our first output is going to be a matrix 4 and we're going to call this our material and then i'm going to add a color normal smoothness occlusion and height now i just need to go through and name these so i'm going to call it color normal smoothness occlusion and height. And now we're going to go ahead and set the data type. So our color is a vector 3. Our normal is a vector 3. And our smoothness and occlusion and height are all vector 1 or floats. Okay, so we're done with our outputs. And now we can just go ahead and hook these up. I'll hook up our material 4x4. I'll hook up our color, normal, smooth. smoothness, occlusion, and height. And now all of our data is being passed out of our subgraph, so it's ready to be a layer. And so let's go ahead and I'll save this. It's called Layer IQ Tile Break. We're going to open up our simple shader. Here's the layer that we created at the very beginning of the series of videos. Then we created this one in episode four, and this is the one that we're going to create today. So I'm just going to go ahead and delete this version that I've already made, and we're going to bring in the one that we're working on now. So it's called Layer IQ Tile Break, and I'll just set it up here and pass it out. And now we'll be able to take a look at what it looks like when we connect it up to the terrain. Just for now, I'm going to pass out the color data and connect that to color, and I'm going to disconnect everything else. And this is just going to make it easier for us to see what's going on in our shader. So I'm just going to save that, and we'll switch here over to our scene. And now you can see that everything's just pure white because we haven't actually done anything with our texture samplers yet. All right, let's switch back to our subgraph. And we're ready to get going kind of with the meat and potatoes of this shader. Okay, the next thing that we're going to do is I'm going to come up here to our blackboard and we're going to create a dropdown. And I'm going to call this dropdown layer. And we're going to set up a couple of layers. So I'll select this and we want to make four layers. And we'll call these 0, 1, 2, and 3. So we've got our layers set up like that. And now we can bring in our layer dropdown here. And they need to pass in index values of 0, 1, 2, and 3. and now what we can do now that we have this layer drop down here is we can bring in our texture samplers for sampling the terrain or sorry not our samplers but we can bring in our textures our texture assets and so we need to use a node called terrain texture and this is a brand new node in unity 6.3 so if you're if you don't have this you probably need to upgrade to Unity 6.3. So you can plug in your layer dropdown here. And what this is going to allow you to do is select which of your layers this texture node is going to be using. So this one's going to be using our diffuse map. And then I'm just going to copy and paste it. And I'm going to set this one to use our normal map. Okay. And then now that I have these set up with the correct layer, I can use the texture asset that's coming out of here, and that's going to give us our diffuse map and our normal map. But we're not going to use those directly into our samplers yet, because we actually need to grab the texture transforms that those maps are using. And so I'm going to drag out my texture asset, and we're going to add a split texture transform here. And this is going to give us the tiling and offset values that our texture is using. And so now I can just add a tiling and offset node. And this is going to give me the correct tiling and offset for that texture. And so now that I have those UV coordinates set up, and I'm going to do the same thing for my normal map texture asset as well. And so now that I have these set up I can plug the split texture transform node the texture only here I can plug these into my samplers So I going to grab this and plug them into my samplers And then the same thing with my normal maps. I'm going to plug these into my samplers. Okay. So this is bringing in the correct texture data for me and plugging those into my samplers. And now I can take this tiling and offset node, and that's going to give me the UV coordinates that I need to start with. So the first thing that I'm going to do with these UV coordinates is I'm going to create DDX and DDY nodes. And that's what we're going to pass into the derivative inputs over here on my texture samplers. So there's my DDX and I'll also create my DDY. And these are going to be used by the texture samplers to calculate the MIP levels correctly. So I'm going to pass in DDX and DDY into all four of my samplers here. Okay, the next thing that we're going to do is bring in some noise. And so I've created a noise texture and show you what this texture looks like. I just called it Gray Noise Medium. And the way that I created this is I set my color palette to 127, 127, 127. So just kind of a medium gray there. And then I selected the medium gray and I came up here under filter, noise, and I picked add noise. And then I set this add noise panel to Gaussian monochromatic and I set the amount to 25%. And that just gave me kind of some medium noise here. By the way, this texture is only 64 by 64. And if we take a look at it in Unity here, you can see that I have set it to single channel red. Ignore PNG gamma. And I set the format to R8. So there's my noise channel. And it's only 64 by 64. It's a very small texture. and because it's so small, a lot of the time it can fit the entire thing into the cache of the GPU. And what that means is that this texture sample is going to be sampled very fast. Normally, I recommend against using texture samples, but because we're using such a small texture we're able to fit it mostly into the GPUs cache and that means it's going to sample really quickly so I'm going to take the UV coordinates that I got here in my tiling and offset node and I'm just going to multiply those UV coordinates by 0.017 and what this is going to do is it's going to make this noise texture really large on my terrain. So I'll just set my multiply to 0.017 and 0.017. And now I'm going to connect up these UV coordinates to my noise sampler. And now what I'd like to do is just pass out my noise as color so that we can take a look at what it looks like on the terrain. So I'm going to connect it to our output color there and save this. Then I'll switch over to this place where we're using our subgraph and make sure that color is connected to our output color. And I'll just save this. So now we can see that we have that noise texture applied to our terrain and it's scaled up really large. So you can see there are kind of these splotches of black and white. That's coming from our noise texture over here. but it's scaled up really, really large. And that's being done by that node that multiplies by 0.017. And you can adjust these values here. You don't have to use 0.017. That's just a value that I found that worked well. One thing that I noticed that I made a mistake on, by the way, is I had my tiling and offset plugged into UV and tiling. So make sure that you have your tiling and offset plugged into tiling and offset here and not into the UV coordinates there. Okay, so we've got our noise texture. And what we're going to do with this texture is we're going to use this as a mask to create eight different zones of different UV offset. And the way that we're going to make those eight different zones, the first thing that I need to do with my mask is multiply it by eight. So I'm going to add a multiply here and we're going to multiply these by eight. And now in order to make these into masks, I have a range of zero to eight now. So the next thing that I'm going to do is add a floor node, which is going to round this down to the nearest value. Now, if we want to visualize what this mask is looking like, we can take this floor net node and we can multiply it by one over seven. So here, what I'm going to do is just multiply because right now our value is between zero and eight and that's not going to show up on our terrain very well. And so I need to shrink that range down just so that we can visualize it. I just doing this temporarily So I gonna multiply this by 0 which is like 1 over 7 and then I gonna pass that out as our color and what this is gonna do is show you all of the different areas and so each of these different shades of gray on our terrain here is gonna become its own little UV Island or an area that has a different UV offset. And we'll come back here to our floor node now. And I have two sets of texture samplers. This is like my first set here. This one is for color and this one is for normal. And then my second set for color and for normal. so I need to create two different sets of texture coordinates for them and for each set I need to to multiply I'm just going to create a vector 2 here and I'm going to set these values to 3 and 7 and so for each of my texture sets the first thing that I'm going to do is multiply by 3 and 7 so that's for my first texture set and my second texture set the next thing that I need to do is use a sine node so I'm going to create a sine wave here for each of the sets and for this set down here I want it to be offset by one phase and so instead of just doing the same thing as that other set there. I'm going to come down here to the second set and I'm just going to add one to it. So the second set is going to be offset by one from the first set. That's what's going to make it different. And now at the beginning of the video, I showed you that we could control the amount of offset that we were adding. And so what I'm going to do here is just create some multiply nodes and we're going to multiply these offsets that we're creating by an offset control. So I'll open up my blackboard here and create a new float control that's called offset. And I'm just going to add that into my multiply here and we'll set up offset to be a value that we can input. Okay, so I'm going to add a multiply here. We're going to multiply those UV coordinates by our offset. And now we can take our UV coordinate offsets that we've created here with our mask. and we can add this these offset values to um our original set of uvs so i'm going to grab our uv coordinates here and we'll bring them down and then we'll add our offsets to them And there we go. And so now we have two sets of UV coordinates. This one has the offsets, and then this one has the offsets, but plus one. And so now we can plug these UV coordinates into our color texture and also our normal texture. And then our second set is going to plug into our color texture and our normal texture. Okay, so we have our texture coordinates all hooked up. We have our textures being sampled here. And the last thing that we need to do is create the mask that we use to blend between the two sets of textures. So the way that we create our mask is we come over here to our value that is multiplying by eight. And we just add a fraction node to round that down to the nearest whole number. So now I can use this fraction as the blend mask between my two sets of textures. So I'll plug that into my first lerp and I'll plug that into my second lerp. Okay, so let's take a look at a couple of things. The first thing that I want to show you is these offset values. So I'm going to connect this up to color so that you can see how these textures are being offset. And our offset multiply value is set to zero. So I need to fix that really quickly. I'll just connect up my blend value here with offset. And that's a multiplier. So if I pick my material, you can see that I can control the amount of offset that's happening. So these colors that you're seeing, this crazy red, green, and yellow, these are my UV offsets. So you can see that each of those eight different areas has now been converted into UV coordinate offsets. And then we add those offsets to the UV coordinates that we're using to sample our textures. So if we switch here and connect up our color value and save that and then switch to our shader, now we can take the material that's coming out of there and connect up our color, our normal, our metallic, our smoothness, and our occlusion. and we should have a nice looking material. Now you'll notice that the tile break is working really well. And that blend value that we connected in our shader, we can use this slider here to say we're not going to apply any texture tile breakup. And now you can see that we've got corn rows off into the distance that look terrible. Or we can dial this in and offset our texture coordinates. and now we've got some really beautiful looking terrain texture with no tiling pattern. Okay, let's switch back to our shader because there is one more thing that I want to do. Right now, we're just using the value coming out of this fraction node directly to blend between our two different textures. but we can do something a little bit more interesting and that is we can use the value from the textures themselves to add a little bit of contrast. So what I'm going to do now just so that we can visualize this is I'm going to take our fraction value and show you what this mask looks like. So here's the mask that we're using to blend between the two textures and you can see that it kind of has these rough edges. And what we want to do to improve the quality of these rough edges is use the brightness and contrast of the textures themselves to blend, to kind of modulate this mask so that we create a little bit more interesting and less geometric mask. And so what I'm going to do is take the result of my texture sample, my color texture samples here. I'm going to use a subtract node. We're going to subtract the second texture sample from the first. And then I'm going to split out my three individual channels into red, green, and blue. And we're going to add these values together. So I'm going to add red with green. And then I'm going to take the result of that and add it with blue. And now we're going to just multiply this, the result of this, by 0.1. This is a value that you can tune a little bit if you want more or less contrast. And now we can take that mask that we created over here with our fraction node and subtract this value that we've just created here from our textures. And this is going to blend in some of the brightness and contrast from our original textures with our mask to blend back and forth between them. And then we can just add down here on the end, we can add a smooth step value. and I'm just going to set my edges to 0.2 and 0.8 just to up the contrast just a little bit and now let's take the result of this mask and plug it in and see how it's different so we'll hit save and come back here to our scene and what you can see now I don't know if you can see this but let me switch this mode over so that we can just see the color I'm going to go to analysis Render Debugger. And I'm going to set our material to just show us the albedo, just the color. So now you can see instead of a smooth gradient, we're using some of the detail from the texture itself to create that mask to break up between the two textures. And that just adds a little bit of interest. So let's switch back to our shader here. And instead of passing out the mask, I'm going to pass out the color and we're going to plug this mask in and use it for blending between our two samples of the textures. All right. So that step is not strictly required. And if you want your shader to be just a little bit cheaper, you can leave that out and just use the output of the fraction node here directly into your two texture blends. But this makes the blends just a little bit nicer, a little bit smoother, and the blends kind of respond to the texture itself. Okay, now one thing that I'm noticing is that the textures aren't very crisp. they're just a little bit soft and so what i'm going to do is switch back here to our sampler state and let's just make sure that our sampler state is set to uh trilinear and our anisotropic filtering is just cranked up a bit yeah and now we've got a much a much nicer crisper result And we can use this blend parameter to control how much of the texture tile breakup we're applying. So this is without any texture tile breakup. You can see there's a ton of tiling there. But then when we apply this technique that we created today, we get zero texture tiling and really nice tile breakup without too much of a cost. I really like this method, and I'm excited to show this to you today. Like I said, this is created by Inigo Chiles, and I'll link his shader toy example of this shader down in the description. All right, let's switch over to Unreal, and I'll show you how to create this same shader there as well. Okay, here we are in Unreal, and you can see we've got our forest scene here, and I'm using our original version of the landscape layer. and you can see that there's a ton of tiling artifacting going on here So what I wanna do is kind of show you kind of the progress that we been making So this is our original simple layer and it looks like this It's just sampling the color texture and the normal texture, the normal occlusion and height. And it's basically as simple as it can be. But you can see that there are a lot of tiling artifacts here and it just doesn't look that great. So if we switch over to our terrain material, what I'm going to do next is plug in the material that we made in episode four. And so this does the version of tile breakup where you sample your textures twice. The second time is rotated 90 degrees and then you blend between the two using a mask. And you can see that this is better than the original. There's a little bit less tiling here, but especially off in the distance, you can still see quite a bit of tiling. So let's switch over to the technique that I'm going to show you how to create today. And we'll save this. And now you can see the texture tiling is practically completely gone. that the technique that I'm going to show you today does a really good job or a lot better than the technique that I showed you in episode four. So we're going to jump in and create that technique today. And in order to save us a little bit of time, what I decided to do is we're going to take this rotation layer material function that we created in episode four. And I'm just going to copy and paste it. And we're going to start there kind of as our starting place. So we'll copy and paste the episode 4 material function. And we're going to call this LayerIQTileBreak. And I call it IQ because it was invented by InigoKillits. Okay, so I'll just open it up and get started. So if you'll recall, in episode four, we were doing two different texture samples. And the first texture sample had its UV coordinates rotated 90 degrees. And we did that 90 degree rotation with this swizzle here. But we're not going to use that today. And so I'm just going to delete this swizzle. We have our texture objects coming in here. we just kind of need to touch this up a little bit and get it ready to to use for what we're going to do today and down here we're sampling our blend mask but we're not going to use a blend mask today we're just going to sample some noise and so I'm going to bring in our noise texture now I've just called this medium gray noise medium. If we switch over to Photoshop, you can see this noise texture is just 64 by 64, and it looks like this. So in Episodes 4 version, we use that mask to blend between our two textures. But instead of doing that, we're going to use the mask to generate UV coordinates for the two textures. So I'm going to take our original UV coordinates and we're going to multiply them by 0.017. And then I'm going to pass these into the UV coordinate slot on our texture. Okay, now because we were rotating our material, I had to use this swizzle node here to re-rotate our normals back. But we don't need to do that this time because we're not using rotation. we're just using offset so i'm going to get rid of that swizzle and that append there and now we're just using our regular lerp okay i think that everything else should be good to go in this material so now we actually need to start on the part that's specific to this technique and that is how we generate the uv coordinates for our two different samples so we we sample this noise the noise texture that i just showed you and i'm going to take the red channel and we're going to multiply it by eight and what this is going to do is it's going to give us eight different zones for different amounts of texture tiling offset so we'll multiply by eight and then we'll add a floor node and this floor node is going to round down to the nearest whole number so we have a range of zero to eight but we're rounding down and again just like i did in unity i'm going to take this temporarily and what i want to do is show you what this mask looks like. And so I'm going to multiply it by 0.143, I think, if I remember correctly. It's 1 over 7. And we're going to pass this out as a color just so you can see what this result looks like. Okay, so this is a pretty good view. And what you can see here is I've got this noise, and I've multiplied it by eight and then rounded it down. And what that gives us is eight different zones. And each of these little zones, each of these different shades of gray is gonna have its own UV offset. And that's gonna break up our tiling. This method works really well, you guys. I'm excited about it. All right, so let's switch back to our material function. this is our multiply by 0.143 and i'm just going to get rid of that again we were just doing that temporarily so i could show you what that mask looked like now we need uh one uh offset for our first material and another offset for our second material and so what i going to do is add a vector 2 node here and i going to give the x value a value of 3 and the y value a value of 7 and we're going to multiply our offset by that and with our second set of uv coordinates before we multiply we need to add one so this was this is going to be one phase off from the first one so we'll just add one and then again we're going to multiply by this three and seven. And now we're going to bring in a sine wave. So I'm going to add a sine here. And I'll add a sine here. Now, one thing that's really important to know is this sine node here works differently than sine in normal mathematics. Normal math sine has a period of 2 pi, which is like 6.2, but this sine has a period of 1. And so in order for this to behave like it did in Unity, we need to switch our period to 6.2, which is a very close approximation to 2 pi so that we get the same results. Our period needs to be 6.2 instead of 1. And now that we've done that, we can take this value and use it as an offset for our UV coordinates. But before we do that, there is one more thing that I want to do here, and that is I'm going to multiply this by an offset input value so that we can control how much of it is is is being added so i'm going to create an input we're going to set it to be a scalar and i'm going to call it offset and we'll check this uh use preview as default value and then i'm just going to multiply my two different sets of uv coordinates by this offset amount and that's going to allow us to control how much of this effect we're we're dialing in okay and then the last step for uh creating my uv coordinates here is to bring in the uvs that we had or that we're using and add our offsets so we're going to add our original uvs here and we're going to add our original uvs here as well okay so we've created our uvs offsets we've added them to our original uvs and now we can just take our uv coordinates and plug them in here and we're going to plug them in here and then our second set of uv coordinates we're going to plug into our second set of textures and i think that's all we need to do i think we're all done so let's go ahead and save our shader and we'll hook it up or we're saving our material function and then in our shader here here is the material function that we just created and we have this offset value so we We want to control that. So I'm just going to bring in a hard-coded value of 1 for now and wire it up. Now with our material function, we're going to plug our material into the getMaterialAttributes. Then we're going to actually, you know what? We don't need that really. Well, it doesn't matter. Then we're going to break it out and plug it into baseColor, specularRoughness, normal. This one is writing to our runtime virtual texture. This is what we learned about last week. And then we're going to plug our color or we're going to bring in our runtime virtual texture sample and pass out the color specular roughness and normal. And we'll save it and we'll switch over to our scene. And now you can see that we've got our really nice tile breakup going on. This tile breakup method works fantastically. what I want to do next is create a material instance and use it so that we can control a parameter so I'm just gonna come down here to terrain and right-click and pick create material instance and we're gonna plug this value in as our material on our terrain instead of what we currently have it we're because we just have the material you use directly right now and I want to plug in our material instance instead. So I'm going to grab that and drop it in. And now as we open up our material instance here, actually, I'm just going to tear this off and let it float there. And now we can control that offset value. And what I need to do in my material here is here's the material function that we just created. here's the offset value we need to add a new input here or convert this one to a parameter I'll just right click on this and pick convert to parameter and we'll just call it offset for now this is just temporary so that we can take a look at what this looks like and so now if we look at our material instance I think we should be able to find yeah there's that offset value so let's switch over to our scene i'll check our offset value on and now we can set this value to zero to get no tile breakup you can see it repeating over and over again and if we uh slowly slide this uh it looks like it not updating in real time But anyway you get the idea If I set this to something higher than zero you know set it to zero we get tons of tiling going on, but something higher than zero, and it starts breaking up the tiling. And if we set it to one, we get the full tile breakup amount. And it looks pretty cool. All right. Now there is one more thing that I want to show you. And that is the fact that we can use, um, we can use the material itself, um, to improve the blending because right now that blend mask doesn't take into account the features in the material at all. So let me show you how to do that. I just noticed that I made a pretty big mistake. Right now, my two textures are being blended by the blue channel of my noise texture, which is wrong. I need to add a frack node. So we're multiplying by eight, then I add a frack. And this is the value that I use to break up or to blend the two different textures. So I'm going to plug this frack node into my lerps and save that. And I should get a much better result now that I'm using the correct value to blend between my two textures. But what I can do is take the result of these two textures and have them actually contribute to this mask that's getting created to blend between them. So let's go ahead and do that now. So what I'm going to do is take the result of this texture here and add a subtract. Then I'm going to subtract this texture from it just to get the difference between the two different samples. And then I'm going to split this out so that we get our red, green, and blue channels. And I'm going to add them together. So I'll add red with green. And then I'm going to add the result of that to blue. and then we're going to take the result of that and we'll just multiply it by 0.1 and now I can take the result of this and subtract it from the mask that we created to blend between our two textures from our frack here so I'm going to grab this and add a subtract and so i'll subtract this mask that we created from adding the three channels together i'll subtract out our mask and now the last step here is i just need to add a smooth step just to kind of adjust the contrast just a little bit so i'm going to pass this into the value of my smooth step and then for my minimum and maximum i'm going to give it a value of 0.2 and a maximum value of 0.8. And this is going to become my new mask that I can now use to blend between my two texture samples. So I'm going to take that and plug that into my LERP here. And I'm also going to use it to blend between my two NOH textures or my normal occlusion and height textures there. And this is going to just increase the contrast of that mask. Let me show you what it looks like. That frack that I started with originally, if we plug that into our color here and we save it, and that's going to look like this. So this is what we're using to blend between our two different textures. but what i can do instead is add in this value here which is going to give us a little bit of it's going to give us a little bit of the flavor of that material itself and apply it to the blending and i don't know how well you can see that because we have our normal map happening here but basically you're going to get some of this um some of the the structure of the underlying material and we're going to use that for blending between the two the two texture samples okay let's put everything back to normal you just wire out our color here and save that and then in our material we can connect up our our runtime virtual texture again our specular or roughness our normal and save it anyway yeah so now we've got some really nice texture tile breakup and the expense of this in terms of performance is about the same as that 90 degree rotation method I showed you in episode 4, but this one is significantly more effective at breaking up terrain texture tiling. Anyway, I hope you enjoyed this one. I really like this method. Like I said, I'll link down in the description to the original version by Inigo Kiles that he posted on ShaderToy. be sure to take a look at that anyway thanks for watching and come back next week we'll continue our series on creating terrain and landscape shaders have a great week