Simple Interactive Grass in Godot

Поділитися
Вставка
  • Опубліковано 23 лис 2024

КОМЕНТАРІ • 106

  • @KasperFrandsen
    @KasperFrandsen  Рік тому +19

    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 10 місяців тому +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  10 місяців тому +3

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

    • @foixa
      @foixa 4 місяці тому

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

    • @nicolasagustinmartinez9310
      @nicolasagustinmartinez9310 3 місяці тому

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

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

  • @jatoxo
    @jatoxo 2 роки тому +8

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

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

  • @sobinec
    @sobinec 10 місяців тому

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

  • @orkmaedchen
    @orkmaedchen 3 роки тому +4

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

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

  • @BastiaanOlij
    @BastiaanOlij 3 роки тому +2

    Brilliantly done and well explained!

  • @TheSkatingAces
    @TheSkatingAces 5 місяців тому

    This was really useful. Thanks a lot!

  • @Hemoplaguer
    @Hemoplaguer 3 роки тому

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

  • @vesk4000
    @vesk4000 3 роки тому +1

    Awesome tutorial!

  • @GreySectoid
    @GreySectoid Рік тому

    Excellent tutorial, thank you.

  • @dodderss
    @dodderss 3 роки тому +1

    This is really cool!

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

  • @childlearningclub
    @childlearningclub 11 місяців тому

    Great Tutorial Thank You!

  • @christophers650
    @christophers650 3 роки тому +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  3 роки тому +2

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

  • @Fallout-experience
    @Fallout-experience 3 роки тому

    Nice tutorial. Thank you!

  • @beebster7
    @beebster7 3 роки тому

    Great little tutorial, many thanks!

  • @TokisanGames
    @TokisanGames 3 роки тому +1

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

  • @hydrak6346
    @hydrak6346 3 роки тому

    Wow really Thank you!!

  • @owenlloyd2528
    @owenlloyd2528 Рік тому

    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.

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

  • @xegrand7548
    @xegrand7548 3 роки тому +1

    Great ! New sub !

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

  • @jorn-jorenjorenson5028
    @jorn-jorenjorenson5028 3 роки тому +1

    Great and inspiring tutorial, thanks for sharing! : )

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

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

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

  • @ethanlucas3002
    @ethanlucas3002 10 місяців тому

    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  10 місяців тому

      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 10 місяців тому

      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!

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

  • @tyreldelaney
    @tyreldelaney 3 роки тому +2

    I 'm working in 2d but this is still giving me interesting ideas. 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.
      ua-cam.com/video/XZOX552W0qM/v-deo.html
      pastebin.com/fS2DjTYw

    • @Silver-nm2if
      @Silver-nm2if 2 роки тому

      @@KasperFrandsen thanks for this

  • @aZaamBie135
    @aZaamBie135 3 роки тому

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

  • @b3daz
    @b3daz 3 роки тому

    Nice.

  • @skreet7251
    @skreet7251 2 роки тому +1

    the grass spreads out at the middle not player pos

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

  • @jatoxo
    @jatoxo 2 роки тому

    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

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

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

  • @Luciferatw0rk
    @Luciferatw0rk 2 місяці тому

    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?

    • @KasperFrandsen
      @KasperFrandsen  2 місяці тому

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

    • @quintin1561
      @quintin1561 6 днів тому

      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

  • @gaschneidr
    @gaschneidr 3 роки тому

    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  3 роки тому

      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 3 роки тому

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

    • @KasperFrandsen
      @KasperFrandsen  3 роки тому

      @@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 3 роки тому

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

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

  • @qbitsday3438
    @qbitsday3438 3 роки тому

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

    • @KasperFrandsen
      @KasperFrandsen  3 роки тому

      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 3 роки тому

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

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

  • @death-dg3ns
    @death-dg3ns 8 місяців тому

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

  • @b1na276
    @b1na276 3 роки тому

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

    • @KasperFrandsen
      @KasperFrandsen  3 роки тому

      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.

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

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

  • @forhadrh
    @forhadrh 3 роки тому

    Lovely! ^_^

  • @jasperbrooks2118
    @jasperbrooks2118 3 роки тому

    Wtf, Good job . .

  • @Gury9478
    @Gury9478 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 :)

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

  • @question_mark
    @question_mark Рік тому

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

  • @ivailoburov1295
    @ivailoburov1295 3 роки тому +1

    Here is an test with wind, however without source code:
    ua-cam.com/video/XZOX552W0qM/v-deo.html
    Such addition will be nice.

  • @iamhatchild
    @iamhatchild 4 місяці тому

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

  • @toooot
    @toooot 3 роки тому

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

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

  • @Galaxie69420
    @Galaxie69420 4 місяці тому

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

    • @KasperFrandsen
      @KasperFrandsen  4 місяці тому

      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.

    • @Galaxie69420
      @Galaxie69420 4 місяці тому

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