Hiding texture repetition in Godot 4 | Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this problem usually happens when you take a seamless texture and use it to cover up a large area you'll get this Earthly repetition effects that might or might not break the immersion of your game and I'll show you two ways you can get rid of that but it's worth mentioning that this is not meant to be a follow along tutorial the goal is that you hopefully will get a grasp of these techniques for yourself and will deploy them in your own projects because the problem isn't always specific to say a material for a Terrain it appears whenever you tie the texture way too many times in any context but with that being said the project files are available to download in the description so to start I've set up this simple scene that you can very easily create for yourself it only needs to have a pain machine then we're going to attach a new Shader material to it and from the create a new Shader we'll call this repetition it'll be of type spatial and also we're going to be using visual shaders for this because we're not evil so click create and now we can open the Shader editor and start from here so I create this texture from textures.com and purposefully increase this contrast in photo p in order to make the repeating patterns more noticeable once we scale it up and now I'll drag and drop it into the editor and change its type to color because it is color data so plug it to Albedo and now to scale it up we're going to take the UV and pass it through a UV scanning node and for the scale value we can just use a float constant which I'm going to set to 5 and there it is now you can definitely see the repetitions for yourself which means we have successfully reproduced the issue yay now we can start working on the fix and to explain what I'm doing here I want to later be able to come back and compare the results we get to the original unaffected node so for each step I duplicate the notes and rename the label and also make their properties unique you don't need to do this if you're watching this video to learn conceptually of course but before continuing any further it helps to have a basic understanding of what we're going to do right now so first we are going to choose a second texture that blends well with our base texture both visually and contextually for instance we can Blended their texture without grass or maybe a must texture with a cobblestone texture you get the ideal but if you can't find a good pair for your case or you simply are not fond of the idea we can instead take the original texture and modify it a bit in different ways and use that but more on that later now we want to make use of a mix note to blend between the textures we have and the way this note works is that it takes into input textures as well as a weight value and the weight value determines which one of the two textures makes it out of the node so if we set it to zero which is black it outputs the first one and if you set it to White which is one it outputs the ladder which means that by using a noise texture instead of a constant number we can create smooth and random transitions between the two textures all across the surface and like I said before instead of using a completely different texture we can instead take the base texture and modify its parameters such as the UVS the brightness and contrast or the Hue saturation value of it and of course there's nothing stopping us from stacking as many of these textures on top of each other as we want to get the results we are happy with likewise we can apply the same techniques to non-color data like normal Maps roughness Maps ambient occlusion Maps or any other Maps as well also one neat thing about this technique is that it doesn't break the UVS of the base texture dramatically meaning that if you're working with the texture with patterns we do actually want to be recognized like bricks or Honeycombs we can still use this technique and maintain those patterns this will not be the case with the next technique as you'll see later so to continue I'm going to duplicate all the notes we have so far and paste them below then I'm going to tweak the scale menu just a tiny bit and then drag and drop the second texture on the texture 2D note then we're going to add a mix Vector 3 node here and connect our textures to its inputs and its output to Albedo now to add the aforementioned noise texture I'm going to copy this texture to the node here and change its texture to a new noise texture 2D then I'm going to select it and in the inspector I'll assign a new Fasteners light to it and here I'm just messing around the noise settings but it doesn't really matter what type of noise you use you just want to set the frequency to something that works best for your case now I plug this into the weight socket and as you can see we are getting the transitions we were looking for but right now because of the nature of the noise textures we are roughly getting the same amount of grass as dirt which might not be what we want so to adjust that your liking in the inspector create a new gradient for the color ramp and start moving and changing the colors until you get the results you are happy with I ended up making the whites a bit darker and also closer to the blacks so that way if we get more ground standard and also the dirt is never really fully opaque to give it a more natural look and again like I said before if instead of this dirt texture we replace it with our grass texture you'll see that it continues to hide the repetitions pretty well actually so that is definitely one way to go now I'll show you how you can directly add variations to the texture itself without the need for another texture and to do that we first need to understand that these textures we have here are currently stored in the RGB format and the way that lets us tamper with a red green and blue channels I am more interested in changing their saturation than hue and to do that we are first going to turn the textures to hs3 by using an RGB to HSV node and then turn them back to RGB via hs3 to RGB node and in between these two nodes we will decompose and recompose them as Vector threes and now the three X Y and Z values correspond to the Hue saturation and the value of the texture note that these values would otherwise correspond to the red green and the blue color channels had been now turned them into HSV first so now to demonstrate if for example I take the Y Channel and then using an add node increase it by 0.3 you can see that the whole texture is uniformly more saturated and of course instead of a constant number we can use a noise texture again so I just copy and paste the noise texture we created before make it unique repressively and change its seed then I use a remap node to remap its values to go from 0 to 0.3 instead of 0 to 1 as they currently do then I'll plug that to the add node and now we can see that the saturation varies based on the noise texture albeit it doesn't really look that great right now but I just wanted to show you how it can be done moving on to the next technique which is a bit different than the one mentioned before in this method we're not going to make direct alterations to the visuals of our texture rather will manipulate the UVS to change the way the texture is displayed across the mesh and just a quick to explain UVS are two-dimensional coordinates that tell your computer how it should display a given texture on a mesh the computer Maps each pixel in the texture to a distinct point in the UVs and as a result any changes made to the UVS seemingly translate to the texture itself directly so to demonstrate if I attack this UV input we added before to Albedo you'll see a visualization of the default uv's dimesh is currently using the u values are horizontally distributed in the red Channel and the B values are vertically shown in the green Channel both scaling from 0 to 1. now if we instead connect the scaled up version of the UVS you'll see everything becomes brighter this is because the UV is now range from 0 to 4 instead of 1. and since our textures are repeatable they automatically tied after values greater than one we'll get a better understanding of what's happening if we pass this connection through a fact operator to client Pizza values between 0 and 1. and that is basically all we're going to do in this technique we are going to use a specific type of noise to randomly move scale and rotate the UVS to break the repetitions but how do we do that exactly we already know that we can move and scale the UVS using the UV scaling and UV panning nodes but unfortunately as of recording this there are no equivalents of those notes for rotation which means we have to implement our own solution now in case you've been following me step by step so far please just stop for a minute and just watch me do what I'm about to do as there's an infinitely better way of doing it that I mentioned afterwards so let's just drag these notes out of the way for now then I'm going to add a UV node and plug it to Albedo so our goal is to rotate this by an arbitrary amount around an arbitrary Pivot Point and it's really easy to do that in gather we only need to decompose and recompost the UVS as Vector to varex and white represents u and v then add a float constant for the amount we want it to be rotated turn that into radians using a radians node get the sine and cosine values of that using the sine and cosine nodes then using multiply nodes we're going to multiply the U value by our cosine and the V value by our sine then using an add note we will add these two values together and this is our rotated U to get the rotated V we are going to multiply the B value by our cosine and the U value by our sine and then subtract the letter from the firmware now if I change the rotation constant from 0 to 90 degrees you'll see that it changed but it's not clear that it's being rotated and that is because currently it's being rotated around the top left corner and ideally we want to be able to specify the center of the rotation ourselves so to do that add a vector 2 constant and set both the X and Y values to 0.5 then we're going to subtract this value from the UVS before we do everything we did using a subtract Vector 2 node and then add it back after we've modified it using an add Vector to note and that's it if we change the rotation value it's much more clearer that it's being rotated but if you're seeing this and thinking to yourself that this is stupid and we shouldn't have to do this every time you want to rotate the UVS you'd be completed right which is why we're going to delete everything but our input values which are the rotation fluid UV input and the Pivot Point Vector too and instead of all of that you will add in an expression node and do everything we did through a couple lines of code so we first have to declare the input variables this expression now takes in which in our case will be a UV invaluable left type Vector 2 a pivot point variable of the same type and the rotation decrease variable of type float and we'll only have one output that is UV out of type vector 2. so we'll take in the UV input the center of the rotation and the amount we want it to be rotated in degrees and if we speed at the rotated UVs and the process is identical to before we first subtract the Pivot Point from the UV input make a new fluid variable conversation gradients and turn our rotation decrease variable into radians using the radians function make a new fluid variable called C to store the cosine of our angle and do the same thing for sine then set you'll be at the Dex or in other words the rotated U to UV in that x times C plus UV in that y times s and set UV add that y to UV in that y times C minus u in dot x times s and of course at the pivot Points back to the UVS variable and we are done so now if I track the input values from before to the Expressions input and plug its output to Albedo you'll see that it does the same thing as before minus the headache then I'm going to copy this extra 2D note here and plug the Expressions output to its UV and now we can see the results in action also needless to say this expression doesn't actually care what type of UV you pass to it it can be the default UVS the screen UVS or for instance I can drag this note group back here and pass the scaled up version of the UVS through this expression node and the rotation is still there and as you may have guessed I'll go this to once again use a noise texture instead of a constant value to rotate different parts of the texture differently but unlike the previous method the type of noise we use here is actually pretty important so pay close attention to the settings here so I'm going to add a new texture to denote here and assign a new noise texture 2D to it then the inspector make a new fastness light set the next time to Cellular and in the cellular tab set the return type to cell value under the fractal tab set the type to none now I'll plug this to alvido to get a better View so basically each cell has a random value between 0 and 1 and based on that we're going to rotate the UVS in each of those cells by a random amount and to start we can directly connect this noise to the rotation degrees input of our expression and at first it doesn't look like anything has changed but that's because the cell values are range between 0 and 1. so it only rotates the UVS by a maximum of 1 degree which is not noticeable and to fix that we can either use a remap node or simply multiply our Noise by 360 and immediately it looks way better and you might think we are done here but if you zoom in we can see that Godot has gone out of its way to let us know that we have created some seams that we now need to hide and thankfully there's a very simple fix for that we just need to copy our noise texture make it unique recursively change absolutely nothing except for the return type which we are going to set to a distance to sub this is very important you have to make sure that any change you make to the first noise like the frequency is also applied to this other one over here then I'm going to use the color ramp and swap the blacks and whites and change them in a way to make a nice follow-up between the two we are trying to highlight the edges here if you couldn't tell now let's plunk the base texture to our video again so this is the one that is being rotated by the noise texture and has the seams now let's make a copy of it and for its UV plug the UV before the rotation so this one is not rotated but also doesn't have seams So the plan is to have this one shown near the edges and the rotated one in the center and to do that we're going to use a mix note again the rotated texture goes to socket a the unrotated one goes to socket B and we'll connect the new noise texture with the highlighted edges to the weight value and with that we have successfully hidden the seams and that's it there's only a few things left to do if you want to alter the UV scale to do it right before the rotation expression using a UV scaling node just remap the same noise texture value to be much smaller and connected to the scale parameter also this is totally unrelated to the topic of this video but if you take the time input and divide it by a big number and then fit it to the pivot point of a rotation expression it makes this cool effect that looks like the current is being sucked into itself you can probably use this to make your mark machiner also because of the chaotic nature of this method I find that even if you use textures that are very clearly not seamless it'll somehow make them look more organic and not out of place and yeah thanks for sticking around goodbye
Info
Channel: quwatz_
Views: 13,019
Rating: undefined out of 5
Keywords:
Id: ssrJGxMtssE
Channel Id: undefined
Length: 16min 4sec (964 seconds)
Published: Tue Aug 08 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.