I added a godot 4 version of the project to the tutorial resources repository. github.com/Arnklit/TutorialResources/tree/main/grass_interact_4 You should also be perfectly fine to follow along in Godot 4 with this in mind: You need to use "model_matrix" the two places where I use "world_matrix" as the name of that matrix was renamed. The script that sends the position to the shader, needs to say "@tool", instead of just "tool" at the top in Godot 4. And when you set the player position in the script, the line needs to be "get_parent().get_parent().get_node("Grass").material_override.set_shader_parameter("player_pos", global_transform.origin)".
Just an FYI you didn’t update the ‘param’ to ‘parameter’ in the godot4 docs. but with that said, thanks so much for making this…incredible work and I’ll be using it in my game.
I'm learning OpenGL in university, everything about it is a huge pain and the shaders are no different :D I'm amazed that someone actually understands this stuff.. huge thumbs up! Also really informative and entertaining video. The end result is so rewarding to see, looks beautiful.
For Godot 3.4.4: When the character isnt interacting with the grass. 1. Use Set() instead of set_shader_param(). In the set define "shader_param/" and then the parameter name defined in the shader
Wonderful. Thanks for this, it was very helpful! (Still not sure how so many visual shader nodes turns into so little shader code but I shall continue to experiment until I get it 😅)
This is a great tutorial! It's going to help me out a lot. Just by the way, in English, what you call a "straw of grass" would be a "blade of grass." IDK, though, there might be some dialect that does use "straw."
Awesome tutorial, thank you for uploading this! For whatever reason (probably something I have misconfigured) when trying to move the player around in the editor (Godot 3.3) the grass doesn't move (double checked to make sure the tool keyword was set). Moving the MultiMeshInstance in the editor shows the grass blades moving around the player, but in dropping my own custom player with movement in the scene and actually running the full scene, grass moves around the custom player as expected.
Thank you allot for this video! How do we do the same thing but with a texture for the triangle meshes? Like a bunch of flowers. Can you please make a dedicated video for that?
If you want to do it with a textured board instead the best approach is to rotate the boards away from the player at the base, instead of pushing at the verts. Here is a written shader that does it. shader_type spatial; render_mode cull_disabled; uniform sampler2D albedo_tex : hint_white; uniform vec4 albedo : hint_color; uniform vec3 player_pos = vec3(0.0); uniform float angle = 1.0; // in radians uniform float radius = 1.0; vec3 rotate (vec3 v, vec3 n, float a) { return v * cos(a) + cross(n, v) * sin(a) + n * dot(n, v) * (1. - cos(a)); } void vertex() { vec3 world_vert = (WORLD_MATRIX * vec4(VERTEX, 1.0)).xyz; // model space to world space vec3 direction = world_vert - player_pos; direction.y = 0.0; direction = normalize(direction); vec3 rotation_axis = cross(direction, vec3(0.0, -1.0, 0.0)); rotation_axis = (vec4(rotation_axis, 1.0) * WORLD_MATRIX).xyz; float dist = distance(player_pos, world_vert); float power = smoothstep(radius, 0.0, dist); VERTEX = rotate(VERTEX, rotation_axis, power * angle); } void fragment() { vec4 tex = texture(albedo_tex, UV); ALBEDO = tex.rgb * albedo.rgb; ALPHA = tex.a; ALPHA_SCISSOR = 0.1; }
I know I am two years late to the party but I really liked your code, yet trying to get the plyer script(line 6 / min: 11:12) to work in godot 4-stable seems to hard for me to manage. Maybe someone can point out what syntax I have to write to make it work, thx in advance :D
Thanks. The best way I know of doing that is using a render texture. you write to the texture whenevery something touches the grass and then you constantly fade out the texture to the grass straightens again after being bent. Here is a test I made with that. it also allows for many characters / objects to interact with the grass. twitter.com/KasperArnklit/status/1614901107171667968
@@KasperFrandsen Anyway to make this work with 2 objects (ore more) I just coverted the visual shader to shader (code) and duplicated the variables in vertex, then duplicated the grass mover to write player_pos2 shader param! Now I'm using this whith grass_movers attached to bone's feet and this is fantastic. Thank you.
@@naurk Ah sounds great! Yeah If Godot had array uniforms, a bunch of objects could be fed to the shader to be interactive, but we'll have to wait for Godot 4.0 for that. Another method that could be used would be a viewport render texture from a top view that captures all the objects that will interact and sends that image to the shader, but I believe that is much more heavy on performance. There is already a written version of the shader, see the direct link in the video description.
Hi Silver, no I don't have a tutorial on that, but basically all you would have to do is to add the windforce and the force of the player pushing on the grass together. One of my friends used my shader and added some ambient wind to it. ua-cam.com/video/XZOX552W0qM/v-deo.html pastebin.com/fS2DjTYw
I've added the exported obj into godot, but for some reason it is see through from one side... Edit: I see it's being culled and setting the cull mode fixes it
Great video! Very comprehensive indeed :3 -- I have a problem though: Say the player is a separate scene from the grass, and the grass scene functions as more of tile, when I place more than one grass scene in my main scene, only one instance responds to player location --- My question is: how to have multiple instances of the same grass scene in main that respond to player location? --- also, could you give picture examples of the texture/viewport technique for actor position you mentioned below? - I get the idea, I just don't know how to implement it! ---- Thanks ^_^
Thanks :). Hmm it should work to use many tiles of grass as long as you make sure they are all using a single material instance of the grass shader. With regards to using the viewport, I had planned a follow up video showing how to do that, I just never got around to it, I'll see if I can get that done. I'd need to play around with it myself a bit to find the best approach.
@@KasperFrandsen I'll have to just persist then! I'm sure it'll work eventually :p --- oh that sounds great! I'll definitely be giving it a watch :) --- Thanks for taking the time to help
You'd need a different setup. What you'd normally do for that is render a texture which is a top view of the world where you keep track of object's locations and use that in the shader for bending the grass
@@Luciferatw0rk you can have the player find the grass object based on a group instead or have the script on the grass and have it find your player object to make the reference.
Add the player in a singleton and reference it ex: GlobalSettings.player. In your player scene set your player as GlobalSettings.player = self. Then you can reference it where ever
Really nice tutorial and effect! Any reason why this wouldn't work in Godot 3.3.4? I've tried following along and the effect is messed up, I even downloaded your shader file and try using that, same messed up effect happen. I have no idea why
@@gaschneidr Hmm I just tried out the project in 3.3.4 and it works fine for me. Yeah if you want to troubleshoot just jump on my discord channel and show off what it does and I'll have a look.
@@KasperFrandsen thanks so much for the response. I'm going to try and see if I've done anything wrong again. I'll jump on discord if the shader is exactly what you showed on the video.
Hi Cidney, it should work fine to have it on a moving body. You can jump on my discord and post your setup and I'll try and see if I can spot the issue, but I might be a bit slow in answering as I'm traveling until Wednesday.
Hmm I I think your best option might be to use another approach to add the grass. You could use the Scatter plugin to generate the grass and place it on top of your GridMap level.
I'm sorry I'm not sure what you mean. You can simply save and load scenes up in the scenes menu in the upper left corner of Godot. If you are talking about resources such as materials and shaders you save and load then by clicking on the fold down menu next to them.
In blender you would probably want to do something very different than this. Probably using physics forces on a hair system. I wouldn't really know the best approach as I mostly use Blender for making game assets rather than final animations.
Man how the hell do you guys come up with this? I really need to learn how to do shader stuff. How's the performance like by the way? Thank you for this content!
Thanks :). The performance impact of doing the interaction should be tiny, it's some pretty basic math applied. Of course rendering thousands of straws of grass will have a cost no matter what.
Hmm this line is sort of bothering me: ;) direction = (vec4(direction, 1.0) * WORLD_MATRIX).xyz // world to local I'm fairly sure it should be this right? Or more understandable at least? direction = (inverse(WORLD_MATRIX) * vec4(direction, 1.0) ).xyz // world to local I understand an orthogonal matrix can be inverted, by simply it's transpose, so I think you reordering the multiplication is exploiting this fact. But it's a bit unexpected while reading (perhaps I'm just a bit rusty). Anyhow great tutorial. Love the results as well.
Might be bad practice to do it like I did, I think you are right that it's more readable to use inverse instead. I might just have picked up a few bad habits by learning as I go with a lot of this stuff.
Hello. Are you using a plain as the ground basis for this? As of now Godot doesn't have plains supported as they intend to remove it from future builds. As such, grass is being applied to all sides of the very thin stretched out basic block I have as the test environment for what I'm working on. Is there a way to adjust the MeshInstance to only apply to one side of a surface?
you are doing it wrong. going back to model view just to have godot go back to world view later is a waste of computational power. world_vertex_coords or maybe skip_vertex_transform should be used instead
I don't believe the is any difference in computation. I'm pretty sure the coordinates will have to be converted back to model space either way before rendering, so if you set world_vertex_coords, Godot is just doing it behind the scenes. I thought it was useful to show people how to move between model space and world space, but yeah the shader could have been simpler with world_vertex_coords.
@@darthnegativehunter8659 Yeah thinking more about it I think you might be right, I might just have had my head up my arse when I did this and not thought it through :). I think I've always had it in the back of my mind that is was bad practice to use world space since I assumed it might cause precision errors in large scenes, so if you could convert a world space force into model space and apply it in model space it would be better, but that might not be applicable in this case.
Lol thanks. What a nice and constructive comment! If only I had enabled an addon that shows all the shortcuts I use on screen as well, maybe that would have helped.
I added a godot 4 version of the project to the tutorial resources repository. github.com/Arnklit/TutorialResources/tree/main/grass_interact_4
You should also be perfectly fine to follow along in Godot 4 with this in mind:
You need to use "model_matrix" the two places where I use "world_matrix" as the name of that matrix was renamed.
The script that sends the position to the shader, needs to say "@tool", instead of just "tool" at the top in Godot 4.
And when you set the player position in the script, the line needs to be "get_parent().get_parent().get_node("Grass").material_override.set_shader_parameter("player_pos", global_transform.origin)".
Just an FYI you didn’t update the ‘param’ to ‘parameter’ in the godot4 docs.
but with that said, thanks so much for making this…incredible work and I’ll be using it in my game.
oh weird. I'll fix that tomorrow if I remember :P
black screen... (Godot 4.2.2 stable) : (
@@foixa you need to add global lights to the project and a Camera3d
I'm learning OpenGL in university, everything about it is a huge pain and the shaders are no different :D I'm amazed that someone actually understands this stuff.. huge thumbs up! Also really informative and entertaining video. The end result is so rewarding to see, looks beautiful.
For Godot 3.4.4:
When the character isnt interacting with the grass. 1. Use Set() instead of set_shader_param().
In the set define "shader_param/" and then the parameter name defined in the shader
This works for this tiny plane, but the multimesh "only" lets you create 65536 instances, which isn't enough for a bigger field
Just create multiple chunks
@@ЧелодойМоловек-б8к Then the game crashes because too much grass is loaded
@@jatoxo You should load only nearby chunks of grass, that's all
O.O this! THIS! I NEEDED THIS!!! Thanks dude ur really helpful and amazing!
@Jody Boysel wha... I don't even use insta XD
Finally, something actually useful! Would be great if you could add some wind to the grass. Thank you!
Very informative - thank you for sharing the code, too! Thats why i like this place here - humanity can grow :)
Really clever. What I like about this is it has opened more possibilities in general. Subscribed bro. Thanks for sharing x
Brilliantly done and well explained!
This was really useful. Thanks a lot!
This is cool, I had made something similar in blender but I have no idea how to make shaders in Godot.
Awesome tutorial!
Excellent tutorial, thank you.
This is really cool!
Wonderful. Thanks for this, it was very helpful! (Still not sure how so many visual shader nodes turns into so little shader code but I shall continue to experiment until I get it 😅)
Great Tutorial Thank You!
This is a great tutorial! It's going to help me out a lot.
Just by the way, in English, what you call a "straw of grass" would be a "blade of grass." IDK, though, there might be some dialect that does use "straw."
Thanks :). Ah yeah I'm not a native speaker, so sometimes a bit of Danish sneaks into my English :).
Nice tutorial. Thank you!
Great little tutorial, many thanks!
Very good tutorial. Great job including both visual and code shaders.
Wow really Thank you!!
Thank you
Awesome tutorial, thank you for uploading this! For whatever reason (probably something I have misconfigured) when trying to move the player around in the editor (Godot 3.3) the grass doesn't move (double checked to make sure the tool keyword was set). Moving the MultiMeshInstance in the editor shows the grass blades moving around the player, but in dropping my own custom player with movement in the scene and actually running the full scene, grass moves around the custom player as expected.
Thanks for the shader, it's really cool!
Is it possible to add more entities that deformate grass like the player?
Happy if it's useful. It is possible to add more entities, but makes the shader quite a bit more complicated.
Great ! New sub !
Doubt. What if we want the grass to be only on a certain portion of the terrain ????
I'd suggest using the Scatter addon to place the grass with in that case :). github.com/HungryProton/scatter
@@KasperFrandsen Thanks
Great and inspiring tutorial, thanks for sharing! : )
Ive try it, seem to function well but I have a weird offset of my avatar position, cant seem to find why tho. Working on it
Thank you allot for this video!
How do we do the same thing but with a texture for the triangle meshes? Like a bunch of flowers.
Can you please make a dedicated video for that?
If you want to do it with a textured board instead the best approach is to rotate the boards away from the player at the base, instead of pushing at the verts. Here is a written shader that does it.
shader_type spatial;
render_mode cull_disabled;
uniform sampler2D albedo_tex : hint_white;
uniform vec4 albedo : hint_color;
uniform vec3 player_pos = vec3(0.0);
uniform float angle = 1.0; // in radians
uniform float radius = 1.0;
vec3 rotate (vec3 v, vec3 n, float a) {
return v * cos(a) + cross(n, v) * sin(a) + n * dot(n, v) * (1. - cos(a));
}
void vertex() {
vec3 world_vert = (WORLD_MATRIX * vec4(VERTEX, 1.0)).xyz; // model space to world space
vec3 direction = world_vert - player_pos;
direction.y = 0.0;
direction = normalize(direction);
vec3 rotation_axis = cross(direction, vec3(0.0, -1.0, 0.0));
rotation_axis = (vec4(rotation_axis, 1.0) * WORLD_MATRIX).xyz;
float dist = distance(player_pos, world_vert);
float power = smoothstep(radius, 0.0, dist);
VERTEX = rotate(VERTEX, rotation_axis, power * angle);
}
void fragment() {
vec4 tex = texture(albedo_tex, UV);
ALBEDO = tex.rgb * albedo.rgb;
ALPHA = tex.a;
ALPHA_SCISSOR = 0.1;
}
@@KasperFrandsen Thank you for your effort and for the script.
I know I am two years late to the party but I really liked your code, yet trying to get the plyer script(line 6 / min: 11:12) to work in godot 4-stable seems to hard for me to manage. Maybe someone can point out what syntax I have to write to make it work, thx in advance :D
This is excellent! In real life, grass doesn't snap straight up when you stop stepping on it. How could this be mimicked in the shader? Thanks again!
Thanks. The best way I know of doing that is using a render texture. you write to the texture whenevery something touches the grass and then you constantly fade out the texture to the grass straightens again after being bent. Here is a test I made with that. it also allows for many characters / objects to interact with the grass. twitter.com/KasperArnklit/status/1614901107171667968
That looks so good, and thanks for the quick reply! This looks a bit out of my skillset, but I'd love to learn how to do this someday!
Man your addons and projects are awesome! Now the problem with Godot 3 remains OpenGl performance.
Thanks a lot :). Well Godot 4.0 with Vulkan is getting closer :).
@@KasperFrandsen Anyway to make this work with 2 objects (ore more) I just coverted the visual shader to shader (code) and duplicated the variables in vertex, then duplicated the grass mover to write player_pos2 shader param! Now I'm using this whith grass_movers attached to bone's feet and this is fantastic. Thank you.
@@naurk Ah sounds great! Yeah If Godot had array uniforms, a bunch of objects could be fed to the shader to be interactive, but we'll have to wait for Godot 4.0 for that. Another method that could be used would be a viewport render texture from a top view that captures all the objects that will interact and sends that image to the shader, but I believe that is much more heavy on performance.
There is already a written version of the shader, see the direct link in the video description.
I 'm working in 2d but this is still giving me interesting ideas. Thanks!
do you have a tutorial on how to make the grass move with the wind but also interact with the player?
Hi Silver, no I don't have a tutorial on that, but basically all you would have to do is to add the windforce and the force of the player pushing on the grass together. One of my friends used my shader and added some ambient wind to it.
ua-cam.com/video/XZOX552W0qM/v-deo.html
pastebin.com/fS2DjTYw
@@KasperFrandsen thanks for this
Could water ripples, be created in a similar method to this?
Yeah should definitely be doable.
Nice.
the grass spreads out at the middle not player pos
is there anything i need to do dofferent in c#? I don't think my player code is properly running in the editor (everything else works fine)
I've added the exported obj into godot, but for some reason it is see through from one side...
Edit: I see it's being culled and setting the cull mode fixes it
Great video! Very comprehensive indeed :3 -- I have a problem though: Say the player is a separate scene from the grass, and the grass scene functions as more of tile, when I place more than one grass scene in my main scene, only one instance responds to player location --- My question is: how to have multiple instances of the same grass scene in main that respond to player location? --- also, could you give picture examples of the texture/viewport technique for actor position you mentioned below? - I get the idea, I just don't know how to implement it! ---- Thanks ^_^
Thanks :). Hmm it should work to use many tiles of grass as long as you make sure they are all using a single material instance of the grass shader. With regards to using the viewport, I had planned a follow up video showing how to do that, I just never got around to it, I'll see if I can get that done. I'd need to play around with it myself a bit to find the best approach.
@@KasperFrandsen I'll have to just persist then! I'm sure it'll work eventually :p --- oh that sounds great! I'll definitely be giving it a watch :) --- Thanks for taking the time to help
Could this be made to work with an arbitrary number PhysicsBodies (and not just the player)?
You'd need a different setup. What you'd normally do for that is render a texture which is a top view of the world where you keep track of object's locations and use that in the shader for bending the grass
My player is a scene in my game and I dont want to have the player scene in this grass scene , how can i make the grass interactive then?
@@Luciferatw0rk you can have the player find the grass object based on a group instead or have the script on the grass and have it find your player object to make the reference.
Add the player in a singleton and reference it ex: GlobalSettings.player. In your player scene set your player as GlobalSettings.player = self. Then you can reference it where ever
Really nice tutorial and effect! Any reason why this wouldn't work in Godot 3.3.4? I've tried following along and the effect is messed up, I even downloaded your shader file and try using that, same messed up effect happen. I have no idea why
Hmm no, I would think it should work fine. I'll see if I can test it tonight or in the weekend and give you an answer.
@@KasperFrandsen thank you so much! I can record a video of how the effect turned out here if it helps
@@gaschneidr Hmm I just tried out the project in 3.3.4 and it works fine for me. Yeah if you want to troubleshoot just jump on my discord channel and show off what it does and I'll have a look.
@@KasperFrandsen thanks so much for the response. I'm going to try and see if I've done anything wrong again. I'll jump on discord if the shader is exactly what you showed on the video.
Hey I’m trying to connect this to a moving body but it isn’t working. Is there a specific way I should do that?
Hi Cidney, it should work fine to have it on a moving body. You can jump on my discord and post your setup and I'll try and see if I can spot the issue, but I might be a bit slow in answering as I'm traveling until Wednesday.
How to save this patch of grass for Gridmap ( is it possible) --- Thank you , excellent tutorial
Hmm I I think your best option might be to use another approach to add the grass. You could use the Scatter plugin to generate the grass and place it on top of your GridMap level.
@@KasperFrandsen Hi Kasper thank you , i am still a beginner , struggling to learn.
But, how to save a file and load it? Plz tell
I'm sorry I'm not sure what you mean. You can simply save and load scenes up in the scenes menu in the upper left corner of Godot. If you are talking about resources such as materials and shaders you save and load then by clicking on the fold down menu next to them.
I'm trying to do this in 2D but it looks weird
Can you please make a tutorial of it in blender animation?
In blender you would probably want to do something very different than this. Probably using physics forces on a hair system. I wouldn't really know the best approach as I mostly use Blender for making game assets rather than final animations.
Man how the hell do you guys come up with this? I really need to learn how to do shader stuff. How's the performance like by the way? Thank you for this content!
Thanks :). The performance impact of doing the interaction should be tiny, it's some pretty basic math applied. Of course rendering thousands of straws of grass will have a cost no matter what.
Hmm this line is sort of bothering me: ;)
direction = (vec4(direction, 1.0) * WORLD_MATRIX).xyz // world to local
I'm fairly sure it should be this right? Or more understandable at least?
direction = (inverse(WORLD_MATRIX) * vec4(direction, 1.0) ).xyz // world to local
I understand an orthogonal matrix can be inverted, by simply it's transpose, so I think you reordering the multiplication is exploiting this fact. But it's a bit unexpected while reading (perhaps I'm just a bit rusty).
Anyhow great tutorial. Love the results as well.
Might be bad practice to do it like I did, I think you are right that it's more readable to use inverse instead. I might just have picked up a few bad habits by learning as I go with a lot of this stuff.
Lovely! ^_^
Wtf, Good job . .
video muito bom cara gostei bastante de sua metodologia de ensinamento :) por favor traga mais videos sobre shaders abraços do Brasil
Thanks. Another one should be coming soon :)
Hello. Are you using a plain as the ground basis for this? As of now Godot doesn't have plains supported as they intend to remove it from future builds. As such, grass is being applied to all sides of the very thin stretched out basic block I have as the test environment for what I'm working on. Is there a way to adjust the MeshInstance to only apply to one side of a surface?
Meshinstance planes are not being removed. Plane colliders are being removed.
@@KasperFrandsen ooohhh! Thank you!
bro... -_-
❤ on ur forehead ahahaahaha
Here is an test with wind, however without source code:
ua-cam.com/video/XZOX552W0qM/v-deo.html
Such addition will be nice.
great.... but you may need a better mic...
Famous in-game effects that players won't notice, but "mobile phones" will burn)
you are doing it wrong. going back to model view just to have godot go back to world view later is a waste of computational power.
world_vertex_coords or maybe skip_vertex_transform should be used instead
I don't believe the is any difference in computation. I'm pretty sure the coordinates will have to be converted back to model space either way before rendering, so if you set world_vertex_coords, Godot is just doing it behind the scenes.
I thought it was useful to show people how to move between model space and world space, but yeah the shader could have been simpler with world_vertex_coords.
@@KasperFrandsen isn't the model supposed to go through this procedure ?
model space -> world space -> view space -> screen space (projection matric)
@@darthnegativehunter8659 Yeah thinking more about it I think you might be right, I might just have had my head up my arse when I did this and not thought it through :).
I think I've always had it in the back of my mind that is was bad practice to use world space since I assumed it might cause precision errors in large scenes, so if you could convert a world space force into model space and apply it in model space it would be better, but that might not be applicable in this case.
Oh my god. You explain blender shortcuts horrendously. I can’t even follow what you’re saying. Why..?
Lol thanks. What a nice and constructive comment! If only I had enabled an addon that shows all the shortcuts I use on screen as well, maybe that would have helped.
@@KasperFrandsen suggestion: pace your videos slower so I don’t have to rewind, also: you need to *say* the shortcuts, cuz nobody wants to rewind