A Simple Foliage Shader

Today we are going to write a very simple 2d foliage shader. We will use a shading language based on the popular OpenGL Shading Language(GLSL). We will assume that you have a basic understanding of what shaders are. If you are not familiar with shaders then refer to our primer on what shaders are and how they work. We will also assume that you’re somewhat familiar with Godot game engine and know how to apply a material to a sprite. The material will have this shader code attached to it. Ok let’s write some code. In your shader file slap this code exactly as shown below.

shader_type canvas_item;
uniform float strength:hint_range(0.0, 1.0);

void vertex()
{
	VERTEX.x+=sin(TIME);
}

And let’s see what this code does and then the explaining….

bamboo leaf

Huh? Nothing? There must be something wrong with this code isn’t it? Well no. You know a sprite has four vertices and we are adding to the vertex positions(Vertex.x) a sin value represented by sin(TIME). But here lies the problem sin(TIME) is a very small value so the vertices are moving but you won’t be able to see it if you don’t zoom in enough. Ok why are we adding a sin value you might ask? The answer is simple we want a nice to and fro swaying movement and we know that sin values oscillate between -1 and +1. So if we add to the vertex positions a sin wave per frame we must get a swaying movement isn’t it?

Ok let’s multiply the sin(TIME) with the strength we defined at the top of the code and let’s see what happens. Our code looks like this now…

shader_type canvas_item;
uniform float strength:hint_range(0.0, 66.0);

void vertex()
{
	VERTEX.x+=sin(TIME)*strength;
}

And this gives us something like this with a strength value of 66…

foliage wave wrong

It looks like the whole plant is moving,definitely not the outcome we wanted. This is happening because we are adding to the positions of all the four vertices when we should be only moving the top two vertices. So the correct way to go about this is adding a sort of gradient so that the strength of the movement decreases with increase in the Vertex.y values. So let’s do that…Our final code looks something like this with a strength value of .47…

shader_type canvas_item;
uniform float strength:hint_range(0.0, 66.0);

void vertex()
{
	VERTEX.x+=sin(TIME)*strength*(1.-VERTEX.y);
}
foliage656

So this looks like the plant is swaying in the wind. As you can see in the code above we have just introduced one more multiplication term (1.-VERTEX.y). We are multiplying by this term because Vertex.y values goes on increasing to 1 as we go down. So when we reach bottom for bottom most vertices the term (1.-VERTEX.y) tends to become zero and the term sin(TIME)*strength*(1.-VERTEX.y) also tends to zero because of this, so the corresponding Vertex.x positions are added with a value which is almost zero. So the bottom most vertices doesn’t have any x movement. Play around with various strength values to mimic a calm peaceful day to a raging storm.

Hope this helped. Cheers!

Further Readings

If you liked this article, then please subscribe to our YouTube Channel. You can also find us on InstagramFacebook and Twitter.

READ – CONNECT – BOOST – CREATE

Related :

Follow :