Part of the Khronos Group

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Make swinging 2D grass with shaders

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2015

    Make swinging 2D grass with shaders

    I am pretty new to shaders thats why I am don't know how to begin making such a shader.
    First of all the situation.
    I have this small(In this example only 2 x 2) tile map, where each tile/quad has his own vertices, with a 2-dimensional position and uv coordinates.
    Click image for larger version. 

Name:	Map.jpg 
Views:	424 
Size:	9.6 KB 
ID:	1592
    (The red rectangles marks the vertices, that have in real the same position, I only draw it on the picture side by side to demonstrate, that the tiles/quads don't use the same vertex)

    I want that the yellow vertices are slowly move a little bit to the right than back and the same to the other direction so the texture is stretched and for example a grass texture would look like it's swinging.
    The green vertices should not move, they simply should stay where they are.
    Now I am wondering me how I know in the vertex shader that the current vertex should move or not?
    Must I give every vertex a additional attribut so I could read in the shader whether the vertex should move or not ?

    Can someone help me, or is that a wrong approach/is there a better way ?
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	Map.jpg 
Views:	236 
Size:	7.8 KB 
ID:	1591  

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Quote Originally Posted by DuffCola View Post
    Now I am wondering me how I know in the vertex shader that the current vertex should move or not?
    Must I give every vertex a additional attribut so I could read in the shader whether the vertex should move or not ?
    The vertex shader only sees individual vertices, not the primitive of which they are a part or the vertex' relation to it (it's common for a single vertex to be part of multiple primitives).

    In some cases, you may be able to use gl_VertexID to infer additional details about the vertex being processed. Otherwise, you'll need to use an attribute.

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2015
    One very cheap way I achieve grass animation is by making some assumption about the alignment of the texture.

    This may not be the same in your case however you can adjust values appropriately.

    Assuming that the grass texture is created in such a way that the base of the grass texture is along the bottom edge of the texture. Using this assumption, we can take the vertex information we have for that vertex's Texture coordinate and use that as a ratio between transformed animated offset and original position.

    In this case, if we assume the base UV coordinate is v=1.0, we can first generate a random offset vector to modify our models position (This can either be done in model space of world space, it doesn't necessarily matter.)


    if we have these 3 uniform variables:

    Code :
    // Input variables
    uniform float time;      // A constantly increasing/changing time value which we can use to create difference over time.
    uniform float random;  // a random value in case you want to change the "start point" of the animation for different objects.
    uniform Intensity;       // wind strength essentially

    We can then generate an offset value using some simple trigonometrical functions:

    Code :
    vec3 offset = vec3( Intensity * (cos( time/1.5 ) * (1.0 - TextureCoord.y)) * sin( in_Position.x + random ),
                               0.25 * sin( 1.5*in_Position.x + 2.0*in_Position.z )* (1.0 - in_TextureCoord.y),
                              Intensity * (cos( time/2.0 ) * (1.0 - TextureCoord.y)) * sin( in_Position.z + 2.0*random),

    Modifying the up-component of the data is optional, by default this can be 0, however having some basic random function can be used to improve the visuals of the grass by adding modifications to the height. This will need to be adjusted to the scale of your game if you do use it.

    Finally, you simply add the offset onto the position:

    Code :
    vec4 object_space_pos = vec4( in_Position.x + offset.x, in_Position.y + offset.y, in_Position.z + offset.z + offset.x/5.0 + offset.y/2.0, 1.0);

    ( I also added the offset x and y to the z to create a little more variation in animation. )

    The important part of code here is the fact that the offset is multiplied by 1.0-TextureCoord.y. What this does is it makes the offset fully effective at the point where the v coordinate is 0, (i.e at the top of grass), but makes it ineffective at the base of grass where TextureCoord.y = 1.0. This is a really nice way of creating quick and easy grass animation off simple data.

    Trig functions are used to make a somewhat natural looking oscillation. The current model space position is used as an offset (realistically, you would probably want to use a world-space offset here then add this onto the world space coordinate after it has been calculated.) As the time value increases inside your program, the grass will oscillate.

    In its current form, this will create a relatively simple form of animation. You can make the animation more complex by introducing additional trig functions, and perhaps rotating the offset such to apply it in the direction of the wind, however this is a little trickier. This works very nicely for basic grass animation in light breezes.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts