Stylized Grass with Wind Effect Shader Graph in Unity Engine - Step by Step Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone in today's video I'll show you how to create this awesome stylized grass shedar graph you will be able to control everything to make the grass matches your game expectations so you can control the near and far color you can create a wind texture that not only changes the color of the grass while it's moving but also it bends the grass by controlling the vertices of each grass blade you can also control the shadow color of the objects that laying its shadow on the grass and but that all it can blend seamlessly with the terrain beneath it so the grass can take the color of the uh texture or terrain beneath it and finally of course we will create a grass sway when there is no wind and that's not all you will learn how to use the terrain tool to create this entire scene from scratch in addition to some tips about how to optimize this Shader graph to get the maximum frames per second as possible so let's get started [Music] let's start from scratch by creating new Unity project I'm using Unity 2022 3.11 and we should choose the template 3D urp let's name the project as tutorial stylized Shader graph you can choose then the organization and we don't need to connect to Unity Cloud then create project let's assume that you have already a 3D model for the grass or you can get free one from Unity asset store here is the one I'm using for this tutorial is the Illustrated nature sample which has all what we need to to start creating the Shader graph so import that to your project then go to the i3d N folder then to the graphics folder then prefabs and select then the plant grass number two you'll see everything in pink but no problem because this asset doesn't support the urp but we will fix that soon that's why we're creating the shadow graph This Grass asset uses the LOD the level of depths but the terrain doesn't support that and we will use terrain to scatter the grass around so first get the first LOD from the prefab by unpacking the prefab and move it moving that outside the prefab then let's rename it to Grass prefab grass prefab and then create a new folder name it prefabs and drag that grass prefab to that folder to create a new prefab let's do a quick fix of this pink issue by creating new material and dragging that new material to the grass then in the base map you choose the grass texture then enable the alpha clipping and set it to 0.5 to start seeing a proper grass of course change the color to Green now let's create the terrain which will hold all the grass so right click 3D object then select terrain since we will use the terrain it's better to unlock all the features related to terrain by going to the package manager choose then Unity registry search for the terrain tools and import that now select the terrain and let's adjust some settings by clicking on the settings button first let's reduce the size of the terrain to 50 by 50 then select paint details Tab and click on the plus button here click detailed mesh then select the prefab that we created the grass prefab now we can start painting grass around if I start painting as you can see we can see scattered grass around but not covering the whole terrain and that's what not what we want so to do it properly you go back to the terrain settings and change the detail scatter mode from coverage mode to instance mode now go back to the detail pent and just click once it will fully cover the terrain with a lot of grass this might impact the performance and here is how you solve immediately by going back to the terrain details to the settings and in the detail resolution and the detail resolution per patch you can reduce that to 32 by 32 then the performance will back good next we can go to the terrain paint tab to raise or lower the terrain to to create some details like Hills or Downs of the terrain so adjust the brush size and TR to add some details to the terrain now the scenes started to look good the only thing is missing is a good sky and for that I found this freest stylized Sky Box that gives great Skies now let's create the Shader graph by right click create Shader graph urp lit Shader graph open the Shader graph and let's start by adding the first property which is the main texture main text then this will allow us to put the grass texture and also we need another property to change the color of the grass so first drag the texture 2D to the Shader graph and we need for that of course sample texture 2D to sample this texture then we connect it to the base color then of course we connect the alpha channel from the texture to the alpha on the fragment to render the grass properly you can also add one more control which is the alpha clip threshold that controls how the grass texture is clipped by the alpha of course save the Shader graph go back to the scene and drag the Shader graph into the grass material to start seeing what happened on the scene so as you can see now we have white grass and we can control the alpha threshold but it's recommended to keep it 0.5 next we need a new parameter which is the color to control the color base color of the grass so just create new parameter type of of color and connect with the base color and also we can control the grass smoothness for that we can create a float to set the value for zero or without that parameter you can set it from the Shad graph to default value zero always because the cross doesn't have smoothness and doesn't reflect uh the sun typically unless it's wet okay now we are ready to create some more advanced steps we need to create gradient for the grass based on the depth and for that we start by view Vector node based on the world space and we calculate the lens between the camera and the world using the lens node and we use that to smooth step between two values which are the near far range we create for that Vector 2 property then we drag it to the shadow graph we use split node to split the X and Y values represented by the red and green channels to put them in the edge one and Edge two where we want the gradient to start and ends so as default values you can set them to 10 and 25 10 for x 25 for y to create the gradient we will use a lurp node to lurp between the gradient that we created using the smooth step and use two colors so we will lurp between the far and near colors using the gradient that we created using the smooth step so we connect this SM step to the T value and we then L between two colors we can then group all those nodes and name them to depth color then connect that to the emission because we will add a lot of colors as we go advanced in this Shad graph so connect the results to the emission not to the base color save go back to the scene and now you can control the near and far colors okay let's start by changing the near color to something yellowish and choose the Four Color to something green or orangish but as you can see seems It's flipped because the near color showing the for color in the scene and vice versa to fix that we simply go back to the Shader graph and we use a one minus node after the smooth step to flip the gradient now we have the gradient correct and now you can play with the near and far range to determine where the gradient starts and ends okay the colors looks faded a bit and that's because the base color was set to Gray and to solve that just change the base color into black and now we have a brighter version of the color to add some shading to the grass we can add uh another color at the bottom of the grass based on the length L of the grass to gain access to the height or the length of the grass we need to gain access to the object node then we will use the scale parameter so let's create a new float and name it height blend then drag the height blend to the ched graph then we will use split node to divide the height blend into the value of the Y of the scale but we here got an error because we divided the position not the scale so just connect the scale to the split node then divide height PL to the Y value set the default value of the height plan to one for now now we need to create a gradient based on the Y values of the game object so we so we start with the position based on the object then we split that to gain access to the Y value so now we created a gradient based on the Y AIS then we do a smooth step between the zero value and the height blend let's keep it for now to default value of one let's keep everything organized and group all those nodes into one group called height blend and of course now we need a color property named bottom color to lurp between the top color color and the bottom color based on the height blend actually we got the bottom color at the upper side so we just flip between the bottom color and the upper color so we connect bottom color to the A and the upper color or the top color to the B so now let's save and go back to the scene and test our bottom color as you can see now we can have the bottom color at the lower portion of the grass and of course you can control how the height Blends based on the height blend parameter so you can adjust that till you get a satisfying result of the grass color let's take this to another level as you can see when the grass doesn't cover some portion of the terrain it shows the terrain beneath it which is not looking nice because the the grass doesn't blend with the terrain texture so what we do we do next is to capture the terrain texture then try to blend it with the grass color to do so we need another camera to render the texture that it is capturing so create a new camera set the projection into orthographic and rotate it into to 90° so it captures the terrain from above and to hold the texture we need to create a render texture so go right click create render texture and let's name it terrain color then we assign that into the output of the terrain camera so just drag the terrain color into the output texture the terrain color and set the size of the texture to 1K 24 both on X and Y Now set the following parameters for the camera to render exactly the terrain only you need to set the camera to orthographic set the size to be half of the terrain size so if your terrain is 50 you set the size of the camera to 25 then set the position also to 25 on the X 25 on the Z and make sure that the Y is 200 so the camera doesn't render the grass itself but only captures the terrain texture okay now let's go back to the shadow graph and empty some space to put the nodes related to blending and rendering the terrain texture we start by the position node based on the world space then we split that to gain access to the x and z uh values because the terrain texture is 2D based B on the X and D axises so next we create a new parameter float to to control the terrain size we use Vector 2 to get the x and z values then we divide those values based on the terrain size to be able to offset the terrain we simply create a new float terrain offset and we add it to the previous node now everything is ready to add the terrain color so for that we create new property type of texture 2D texture color and we need a sample texture 2D to render that of course we select the uh terrain color render texture to be rendered there then we connect the previous nodes that we created into the UV let's group everything into one group called terrain color next we add the terrain color to the top color before blending it with the bottom color the shadder graph go back to the scene select the terrain color the render texture and you can see it start blending with the terrain texture beneath the grass we currently doesn't have any texture it's only the checkbox checkboard that we are rendering so let's get some nice textures you can grab for free those nice hand painted grass and ground textures import them to your project now go back to the terrain select the terrain and select the terrain paint tab then select paint texture and start adding terrain layers from the textures that we downloaded I got different grades of green and one dirt and one dark dirt so as you can see the top layer will be the default layer to colorize the uh texture okay so choose which one you like then you use the brush to start painting based on the currently active layer so feel free to be creative and start painting the terrain the way you like and of course I intentionally reduce the resolution of the detail to be able to see the terrain and after you finish drawing or coloring the terrain feel free to return the detail resolution back to 64x 64 and now as you can see see we perfectly blending the texture color with the GL grass color that gives realistic and awesome visually stunning view as you can see the colors a little bit faded and to give more Vivid colors we can give more power to the terrain color by reducing the power of the uh top color to do so we use a multiply node and we multiply the top Colors by 0.25 by giving them 25% of power so that means the terrain color will be more powerful and occupy 75% of the color blend okay now we have two more issues to deal with first one is that if we put an game object on the grass it will render its color on the grass beneath as you can see this cube is rendered as white square under on the grass the second matter we can see the Shadows so let's solve the Shadow and also remove this rendered area of the objects above the grass to render the shadow as I mentioned in my previous tutorials if you watch my Channel or we watched the online course we need a custom function to gain access to the shadow attenuation or the light Direction so I will repeat that quickly to do so you need to download uh a custom script which is the custom lighting from the link I provide you down in the description this script allows you to gain access to the light Direction and also to the shadow so just copy those script script into new text file and save it as hlsl file then import that file into unity and create a custom function node so click on the custom function node and point the source to the light script that we imported and copy the name of the function which is the main light then we need to uh put the inputs and the output puts parameters in the custom function so as an input we just need the world position as Vector 3 for output we need four parameters uh Vector 3 for the direction of the light Vector 3 for the color of the light and float for the distance attenuation and finally we need the shadow attenuation which which will be which will be use to render the shadow once you entered everything correctly the custom function node will show a yellow color for the input we just need the position node based on the world space then of course we need a new paramet parameter the shadow color to control the color of the Shadow then we use another LP node to blend between the terrain color and the shadow color so we will blend between the shadow color multiplied with the terrain color and the terrain color itself so create a lurp node connect the shadow attenuation to the T value on the lurp then to the a value connect the multiplied Shadow color with the terrain color and to the B value connect the terrain color we can also toggle a Boolean to choose between using the bottom color only or between using the terrain color so create new Boolean and connect the bottom color to the off and the last lurp into the on then connect the result to the a value on the lurp next to that let's organize all the nodes related to The Shadow and the bottom color in one group and keep things clean save the Shader graph and let's go back to the scene to see if the shadow has been rendered select the material and click on use to rain color and we can see that the Shadows has been started to be rendered on the grass the second issue can be solved easily because we are rendering on the terrain color all the objects that the camera sees to solve that we simply tell the camera only to render some objects which is the terrain in our case to do so we select the terrain color camera and we tell it to not render anything except one layer so we will create a new layer called terrain and we tell the calling mask to render that only so create new layer name it terrain select the terrain and make it on the terrain layer then go back to the terrain color camera and let it only render the terrain in the coling bask so now the uh color of the cube not rendered on the grass while we still can see the shadow you can make the shadow more Vivid by inre inreasing the height blend and changing the shadow color but as you can see that causes another issue where the grass is also showing some Shadow color at the bottom [Music] level the solution for that issue is very easy we turn off cast Shadows on the material of the grass prefab and it might not be updated uh instantly to the terrain details which is the grass there so turn off the cast Shadow then go to to the terrain to uh paint details of course applies the changes to the grass prefab then go to the terrain select the detail paint then right click on the grass prefab click edit so it will automatically then refresh and now we can see the shadow properly and also the grass color vividly so now we finished with everything related to the grass coloring now it's time to animate the grass realistically using the vertex segment in the Shader graph and specifically by adjusting the position of the vertices in the Shader graph the first idea that comes to the mind for creating a random movement is using a gradient noise so let's create a gradient noise node and set for now the scale to five then we will use tiling and offset node to animate this noise to do any animation of course we need time so create also a Time node and to control the wind speed we need a new float name it wind speed and you can use a vector two to set the the Y value to zero and connect and multiply the time with the window speed then connect it to the offset then connect the tiling and offset to the UV of the gradient noise now we are doing the movement in all axes but we want it to be happening only on the x and z axis because if we want it to move to be on the Y AIS it will be moving up and down which is not logical and for that we multiply the gradient noise with the vector three and we set the Y values to zero so now we created the adjustments of the position we need to add those adjustments to the current position of the vertices so we use an add node to add those movements to the position of the object we can also control the the wind intensity by multiplying the gradient noise with a new float wind intensity before removing the Y values save the Sher graph and go back to the scene you'll start seeing the grass swaying but it's unrealistic because the wind intensity is too much so reduce that to 0.2 is good and sets the speed to 0.1 and we will get nice calm swaying movement of the grass now let's take this animation into an advanced level what if we want to create waves of winds like what you see in AAA games like flower or maybe God of War where you see that the waves of wind you can notice them across the midow or grass fields so let's do that but first of course we will need a texture this texture is hard to be generated randomly and for that we will need a wind texture so first let's get sample texture 2D and create a new property wind texture we will find one free on the internet so after Googling a bit I found this nice wind texture that will do the purpose of the wind movement so let's save that and import it to Unity then go to the shadow graph and just select the wind texture that we have just imported the wind texture will affect all the grass across the scene so we should use the world space for that and yes we start with position node using the world space then we split that position to get the x and z values representing the texture itself like how we did with the terrain color to control the wind noise scale we divide what we reach on a new float called wind noise scale and to animate the wind noise of course we will need a Time node but we divide that by 20 to reduce the speed of movement of the wind noise compared to the swaying of the grass to control the wind noise speed let's create new float then we multiply it with the time that is divided by 20 then we add both the position of the texture to the wind noise speed then we link that to the UV of the wind texture Now to control the contrast of the wind waves or the wind noise let's create a vector 2 name it wind noise contrast then we split it using a split node to represent the edges of the wave so use SM smooth step node and then use the splitted X and Y to represent the edge 1 and two and of course connect the sample texture to the to the input of the smooth step we want the wind to affect only the upper portion of the grass but currently it's doing the opposite it's affecting the button portions to reverse the effect we use a negate node and also to control what is the length of the upper side of the grass to be affected by the wind we create a new float and we name it wind height we negate that then we mult multiply that with the smooth step that that we created previously let's group all the nodes that we created and name it as wind noise texture and rearrange a bit the Shad graph to be more organized let's move the noise texture above and keep the grass sway beneath it then we will use an add node to add the wind noise effect to the grass sway so create an ad node exactly after we multiplied the gradient noise with the wind intensity then link it to the multiply to the next multiply and as you can see now there is a problem that we can't connect the wind noise to the add or the multiply in the grass way and that's because we used the sample texture 2D which does not support the level of depth so so remove the sample texture 2D and use instead of it sample texture 2D but the LOD version of it then connect the sample texture 2D to the in the in of the smooth step and use the wind texture and connect the previous node to the UV then you can connect or add the noise of the wind to the grass way let's save and go back to the scene select the grass prefab and make sure that you have assigned the wind texture you might not feel the effect because the window noise scale is very small but if you increase it to something like 40 on the X and 100 on the Y you can start realizing that there are some wind waves moving across the grass let me Zoom a little little bit on that hill so you can see the effect clearly so check here you can see the waves moving across the grass it might be a little bit not obvious but we will make it very clear in the next steps we will use the wind noise to coloriz the grass itself to make the waves of wind clear for the player for now you can play with the wind noise speed and the wind noise contrast to get various effects how sharp it the wave is how speed is the noise and of course you can change the wind height but going to an extreme values could break the effect okay so what we will do next is to use the w wind noise to colorize the areas that is affected by the wind but first let's reorganize the Shader graph to empty as space for adding specific nodes to do this implementation so we will use the wind texture after we did the smooth step to it and we add it to the depth color and of course adding two values can be more than one so to avoid getting pinkish areas on the texture we make sure that we saturate it and by saturate we mean we clamp all the values between 0er and one then we multiply the saturated value with the height blend before using it as an input for the next lurp you can check that the wind is affecting the upper side of the grass with the white color which is the wind save the shadow graph and go back to the scene and if you can't see the wind color yet you just need to lower the height blend value to be around one of course changing the wind noise speed or the wind noise contrast or the wind height will affect Al the AL Al the color of the wind since we are using the same texture to animate and colorize the grass at the same time okay to make the grass color looks more Vivid and bright you can add to the global volume uh color adjustments so if you don't have any volume yet you can just create a new game object add a volume component then create a new profile here then click add override ride post processing and then then you choose the effect that you want to add and for us I chose color adjustments you can enable all the features or the ones that you will use and we will just increase the saturation till we get that bright cartoonish stylized color see here is zero saturation here is 25 it's also green color now you can also as an extra ad venient to darken the edges of the camera it might be more artistic and next to make sure that we have great performance you can follow the following tips first I've created FPS display to display the number of frames per second when we run the grass and here is what you can do to ensure to to get the best performance in your in your scene no matter how many grass is is on the terrain so first you go to edit project settings sorry preferences then go to the core render pipeline make sure that the additional properties visibility has been set to all visible then you go to the project settings go to the Quality double click on the urp uh asset render pipeline then make sure that the dynamic batching has been enabled also go to the grass prefab and on the material go down to the bottom and enable GPU instancing then go to the terrain settings check draw instance and reduce the detail density to 0.5 you can try not to avoid 32x 32 for detail resolution for me a found 16 for detail resolution per patch and detail resolution 32 gives the best results now if I click play if you check the performance we having now 100 frame per second which is very smooth for any video game and finally I've added some assets to decorate the scene and then created a cut scene using cinem machine to get this final awesome [Music] result [Music] I would like to thank K day. nen for sharing this Shadow graph with us you can check out his Twitter and also his art station page where he publish a great and awesome stylized art if you would like to learn more about shedder graph you can check my course on UD the ultimate 2D and 3D shedder graph course where you can learn the basics and master the skills required to create any visual effect or Shader that you imagine for your video game I have placed a special discount code link down in the description in addition to that you can find links to all the assets that I've used in this tutorial also down in the description and that's it for today's video If you enjoyed this tutorial and and learn something from watching this don't forget to hit like subscribe and the notification Bell to keep notified about the new tutorials and experiments of course we are deeply thankful to our supporters on patreon who keep encouraging us to create such tutorials and of course if you become a patreon you can download all the projects that we have published on this channel till next video see you soon [Music] [Music] la
Info
Channel: Binary Lunar
Views: 7,393
Rating: undefined out of 5
Keywords: BinaryLunar, Binary Lunar, Shader, Shader Graph, Stylized Grass, Stylized Grass Shader Graph, Grass Shader, Grass wind effect, vivid cartoonish grass, video game development, Unity terrain, Unity terrain grass, toon fantasy nature, Shader Graph Tutorial, Unity 2024 Shader Graph Tutorial, Gamedev, step by step tutorial, learn Unity, Stylized Grass with Wind Effect Shader Graph, Unity Engine - Step by Step Tutorial
Id: IjfBlUtJF_0
Channel Id: undefined
Length: 40min 47sec (2447 seconds)
Published: Sun Jan 14 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.