Simple Interactive Grass in Godot

Поделиться
HTML-код
  • Опубликовано: 4 авг 2024
  • Join me on Patreon: patreon.com/arnklit
    Join my discord: / discord
    This simple shader can be used to imitate the player interacting with foliage. It's limited to just one object interacting.
    Software Used:
    Godot 3.2.4.rc1
    Blender 2.91
    Example Project:
    github.com/Arnklit/TutorialRe...
    Direct Link to Shader:
    github.com/Arnklit/TutorialRe...
    Intro - 0:00
    Scene setup - 0:22
    Making a straw model in Blender - 0:52
    Generating a field of grass - 2:46
    Making the visual shader - 3:35
    Driving the shader with a script - 10:49
    Written shader walkthrough - 11:55
    Outtro - 12:55

Комментарии • 103

  • @KasperFrandsen
    @KasperFrandsen  10 месяцев назад +15

    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)".

    • @XanaGear
      @XanaGear 7 месяцев назад +1

      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.

    • @KasperFrandsen
      @KasperFrandsen  7 месяцев назад +3

      oh weird. I'll fix that tomorrow if I remember :P

    • @foixa
      @foixa 17 дней назад

      black screen... (Godot 4.2.2 stable) : (

    • @nicolasagustinmartinez9310
      @nicolasagustinmartinez9310 5 дней назад

      @@foixa you need to add global lights to the project and a Camera3d

  • @vojtastruhar8950
    @vojtastruhar8950 3 года назад +24

    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.

  • @BastiaanOlij
    @BastiaanOlij 3 года назад +2

    Brilliantly done and well explained!

  • @PrimoNelson
    @PrimoNelson 3 года назад +1

    Really clever. What I like about this is it has opened more possibilities in general. Subscribed bro. Thanks for sharing x

  • @orkmaedchen
    @orkmaedchen 3 года назад +4

    Very informative - thank you for sharing the code, too! Thats why i like this place here - humanity can grow :)

  • @beebster7
    @beebster7 3 года назад

    Great little tutorial, many thanks!

  • @vesk4000
    @vesk4000 3 года назад +1

    Awesome tutorial!

  • @TheSkatingAces
    @TheSkatingAces Месяц назад

    This was really useful. Thanks a lot!

  • @stephanleuven5216
    @stephanleuven5216 2 года назад +5

    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

  • @GreySectoid
    @GreySectoid Год назад

    Excellent tutorial, thank you.

  • @Fallout-experience
    @Fallout-experience 3 года назад

    Nice tutorial. Thank you!

  • @shines4031
    @shines4031 3 года назад +5

    O.O this! THIS! I NEEDED THIS!!! Thanks dude ur really helpful and amazing!

    • @shines4031
      @shines4031 3 года назад

      @Jody Boysel wha... I don't even use insta XD

  • @dodderss
    @dodderss 3 года назад +1

    This is really cool!

  • @jatoxo
    @jatoxo Год назад +8

    This works for this tiny plane, but the multimesh "only" lets you create 65536 instances, which isn't enough for a bigger field

    • @user-pj1ox2vo3o
      @user-pj1ox2vo3o Год назад +1

      Just create multiple chunks

    • @jatoxo
      @jatoxo Год назад

      @@user-pj1ox2vo3o Then the game crashes because too much grass is loaded

    • @user-pj1ox2vo3o
      @user-pj1ox2vo3o Год назад +3

      @@jatoxo You should load only nearby chunks of grass, that's all

  • @childlearningclub
    @childlearningclub 8 месяцев назад

    Great Tutorial Thank You!

  • @drentsoftgames
    @drentsoftgames 2 года назад +1

    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 😅)

  • @hydrak6346
    @hydrak6346 3 года назад

    Wow really Thank you!!

  • @sobinec
    @sobinec 6 месяцев назад

    Finally, something actually useful! Would be great if you could add some wind to the grass. Thank you!

  • @spotlessapple
    @spotlessapple 3 года назад

    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.

  • @Hemoplaguer
    @Hemoplaguer 3 года назад

    This is cool, I had made something similar in blender but I have no idea how to make shaders in Godot.

  • @TokisanGames
    @TokisanGames 3 года назад +1

    Very good tutorial. Great job including both visual and code shaders.

  • @xegrand7548
    @xegrand7548 3 года назад +1

    Great ! New sub !

  • @owenlloyd2528
    @owenlloyd2528 Год назад

    Thank you

  • @jorn-jorenjorenson5028
    @jorn-jorenjorenson5028 3 года назад +1

    Great and inspiring tutorial, thanks for sharing! : )

  • @christophers650
    @christophers650 2 года назад +1

    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."

    • @KasperFrandsen
      @KasperFrandsen  2 года назад +2

      Thanks :). Ah yeah I'm not a native speaker, so sometimes a bit of Danish sneaks into my English :).

  • @forhadrh
    @forhadrh 3 года назад

    Lovely! ^_^

  • @vaveexplorer
    @vaveexplorer 2 года назад +1

    Thanks for the shader, it's really cool!
    Is it possible to add more entities that deformate grass like the player?

    • @KasperFrandsen
      @KasperFrandsen  2 года назад

      Happy if it's useful. It is possible to add more entities, but makes the shader quite a bit more complicated.

  • @b3daz
    @b3daz 3 года назад

    Nice.

  • @flow1194
    @flow1194 2 года назад

    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)

  • @yvesgingras1475
    @yvesgingras1475 Год назад

    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

  • @jasperbrooks2118
    @jasperbrooks2118 3 года назад

    Wtf, Good job . .

  • @tyreldelaney
    @tyreldelaney 3 года назад +2

    I 'm working in 2d but this is still giving me interesting ideas. Thanks!

  • @hiltontalles9478
    @hiltontalles9478 3 года назад

    video muito bom cara gostei bastante de sua metodologia de ensinamento :) por favor traga mais videos sobre shaders abraços do Brasil

    • @KasperFrandsen
      @KasperFrandsen  3 года назад +1

      Thanks. Another one should be coming soon :)

  • @lifesymbiont5769
    @lifesymbiont5769 2 года назад

    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?

    • @KasperFrandsen
      @KasperFrandsen  2 года назад

      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;
      }

    • @lifesymbiont5769
      @lifesymbiont5769 2 года назад

      @@KasperFrandsen Thank you for your effort and for the script.

  • @ReversedFootage
    @ReversedFootage 3 года назад +7

    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!

    • @KasperFrandsen
      @KasperFrandsen  3 года назад +8

      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.

  • @naurk
    @naurk 3 года назад +1

    Man your addons and projects are awesome! Now the problem with Godot 3 remains OpenGl performance.

    • @KasperFrandsen
      @KasperFrandsen  3 года назад +4

      Thanks a lot :). Well Godot 4.0 with Vulkan is getting closer :).

    • @naurk
      @naurk 3 года назад

      @@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.

    • @KasperFrandsen
      @KasperFrandsen  3 года назад +2

      @@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.

  • @Local_Nerd_
    @Local_Nerd_ 2 года назад

    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?

    • @KasperFrandsen
      @KasperFrandsen  2 года назад +1

      Meshinstance planes are not being removed. Plane colliders are being removed.

    • @Local_Nerd_
      @Local_Nerd_ 2 года назад

      @@KasperFrandsen ooohhh! Thank you!

  • @aZaamBie135
    @aZaamBie135 3 года назад

    Could water ripples, be created in a similar method to this?

  • @Sinsta13
    @Sinsta13 3 года назад

    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 ^_^

    • @KasperFrandsen
      @KasperFrandsen  3 года назад +1

      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.

    • @Sinsta13
      @Sinsta13 3 года назад

      @@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

  • @cuppixd4267
    @cuppixd4267 Год назад +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

  • @catdog8444
    @catdog8444 3 года назад

    Could this be made to work with an arbitrary number PhysicsBodies (and not just the player)?

    • @KasperFrandsen
      @KasperFrandsen  3 года назад

      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

  • @xegrand7548
    @xegrand7548 3 года назад +1

    Doubt. What if we want the grass to be only on a certain portion of the terrain ????

    • @KasperFrandsen
      @KasperFrandsen  3 года назад +2

      I'd suggest using the Scatter addon to place the grass with in that case :). github.com/HungryProton/scatter

    • @xegrand7548
      @xegrand7548 3 года назад

      @@KasperFrandsen Thanks

  • @Silver-nm2if
    @Silver-nm2if 2 года назад

    do you have a tutorial on how to make the grass move with the wind but also interact with the player?

    • @KasperFrandsen
      @KasperFrandsen  2 года назад +1

      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.
      ruclips.net/video/XZOX552W0qM/видео.html
      pastebin.com/fS2DjTYw

    • @Silver-nm2if
      @Silver-nm2if 2 года назад

      @@KasperFrandsen thanks for this

  • @jatoxo
    @jatoxo Год назад

    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

  • @cidneyowen5589
    @cidneyowen5589 Год назад

    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?

    • @KasperFrandsen
      @KasperFrandsen  Год назад

      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.

  • @gaschneidr
    @gaschneidr 2 года назад

    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

    • @KasperFrandsen
      @KasperFrandsen  2 года назад

      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.

    • @gaschneidr
      @gaschneidr 2 года назад

      @@KasperFrandsen thank you so much! I can record a video of how the effect turned out here if it helps

    • @KasperFrandsen
      @KasperFrandsen  2 года назад

      @@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.

    • @gaschneidr
      @gaschneidr 2 года назад

      @@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.

  • @mohitpandey708
    @mohitpandey708 3 года назад +1

    But, how to save a file and load it? Plz tell

    • @KasperFrandsen
      @KasperFrandsen  3 года назад +1

      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.

  • @question_mark
    @question_mark Год назад

    bro... -_-
    ❤ on ur forehead ahahaahaha

  • @ethanlucas3002
    @ethanlucas3002 7 месяцев назад

    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!

    • @KasperFrandsen
      @KasperFrandsen  7 месяцев назад

      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

    • @ethanlucas3002
      @ethanlucas3002 7 месяцев назад

      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!

  • @KyleLuce
    @KyleLuce 3 года назад

    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.

    • @KasperFrandsen
      @KasperFrandsen  3 года назад

      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.

  • @b1na276
    @b1na276 2 года назад

    Can you please make a tutorial of it in blender animation?

    • @KasperFrandsen
      @KasperFrandsen  2 года назад

      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.

  • @skreet7251
    @skreet7251 2 года назад +1

    the grass spreads out at the middle not player pos

  • @qbitsday3438
    @qbitsday3438 2 года назад

    How to save this patch of grass for Gridmap ( is it possible) --- Thank you , excellent tutorial

    • @KasperFrandsen
      @KasperFrandsen  2 года назад

      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.

    • @qbitsday3438
      @qbitsday3438 2 года назад

      @@KasperFrandsen Hi Kasper thank you , i am still a beginner , struggling to learn.

  • @death-dg3ns
    @death-dg3ns 5 месяцев назад

    I'm trying to do this in 2D but it looks weird

  • @ivailoburov1295
    @ivailoburov1295 3 года назад +1

    Here is an test with wind, however without source code:
    ruclips.net/video/XZOX552W0qM/видео.html
    Such addition will be nice.

  • @toooot
    @toooot 3 года назад

    Famous in-game effects that players won't notice, but "mobile phones" will burn)

  • @iamhatchild
    @iamhatchild 14 дней назад

    great.... but you may need a better mic...

  • @darthnegativehunter8659
    @darthnegativehunter8659 2 года назад

    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

    • @KasperFrandsen
      @KasperFrandsen  2 года назад

      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
      @darthnegativehunter8659 2 года назад

      @@KasperFrandsen isn't the model supposed to go through this procedure ?
      model space -> world space -> view space -> screen space (projection matric)

    • @KasperFrandsen
      @KasperFrandsen  2 года назад

      @@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.

  • @GalaxieTheDev
    @GalaxieTheDev 25 дней назад

    Oh my god. You explain blender shortcuts horrendously. I can’t even follow what you’re saying. Why..?

    • @KasperFrandsen
      @KasperFrandsen  25 дней назад

      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.

    • @GalaxieTheDev
      @GalaxieTheDev 24 дня назад

      @@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