I am new in Ogre and shader, and need some help with wind control on a tree branch

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
vincentdoan86
Gnoblar
Posts: 3
Joined: Wed May 31, 2023 4:11 am

I am new in Ogre and shader, and need some help with wind control on a tree branch

Post by vincentdoan86 »

Hi guys,

I am a beginner in Ogre and shaders to use to animate static objects. I have a project about a scene that I created myself. I am using ogre3d 1.7 and DirectX 9 to load HLSL-type shaders. Below I have an image of a maple tree in my scene, and the mesh of the tree will include the branch and load a separate texture for the branch and leaf. I want to write a shader that can simulate a tree branch and leaves moving as if the wind is blowing through it, like the grass example. I wrote a small shader part, but it didn't help, Does anyone have any ideas or examples that can help me to find this solution without interfering with the engine, hope everyone can help me, and below is the image, the basic shader code that I did, everyone can see and give me suggestions.

Image

This is the shader that I made:

Code: Select all

vertex_program windsControl_VS hlsl
{
	source winds.hlsl
	entry_point main_vs
	target vs_3_0
	
default_params
{
	param_named_auto WorldViewProj worldviewproj_matrix
	
	param_named windDirection float2 1 2
	param_named windStrength float 10
}
}

fragment_program windsControl_PS hlsl
{
	source winds.hlsl
	entry_point main_ps
	target ps_3_0
	
default_params
{
	param_named windSpeed float 10.0
	param_named time float 1.0
}
}

Code: Select all

struct VS_INPUT
{
    float4 position : POSITION;
    float2 uv : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 position : POSITION;
    float2 uv : TEXCOORD0;
    float2 windOffset : TEXCOORD1;
};

VS_OUTPUT main_vs(VS_INPUT input,
    uniform float4x4 WorldViewProj,
    uniform float2 windDirection,
    uniform float windStrength
)
{
    VS_OUTPUT output;
    output.position = mul(WorldViewProj, input.position);
    output.uv = input.uv;

// Calculate offset based on wind direction and wind strength
output.windOffset = windDirection * (windStrength * input.position.y);

return output;
}

float4 main_ps(VS_OUTPUT input,
    uniform sampler2D inputTexture : register(s0),
    uniform float time,
    uniform float windSpeed
) : COLOR
{
    // Calculate texture offset based on wind speed and time
    float2 windOffset = float2(sin(time * windSpeed), cos(time * windSpeed));

// Apply offset to texture coordinates
float2 newUV = input.uv + input.windOffset + windOffset;

float4 color = tex2D(inputTexture, newUV);
return color;
}

rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: I am new in Ogre and shader, and need some help with wind control on a tree branch

Post by rpgplayerrobin »

I think this approach is too naive, because since you cannot know the direction of the current branch.
That means that the main branch, which would normally stay completely still in the wind, would also be affected by the shader.

Also, I don't get why the UV would change just because of the wind. That does not make sense. Only the vertices positions/tangents/normals should move.

If that main branch would always be in the middle and not be bent in any way, you could get the x/z coordinates and see if they are further from the middle, and then multiply the wind value with the distance from the middle (making branches further away get affected by the wind more), but you can also clamp it of course (the only point here is so the main branch does not get affected by the wind).

But if the main branch is a bit bent, you will have a tougher time to do this only in a shader.
If you want to have full control over this, I would implement it in a skeleton instead.
That way, you can move the bones in code to simulate the wind instead. This could also later be expanded to having physics based elements on the tree (like dynamic forces, like an explosion nearby would also affect the tree).
This physics based solution would also make it possible to have different mass of each bone, which would make the main branch being able to move as well, but it would behave like it would be much harder to move (like the explosion would move the entire trees bones, but since the mass of one bone would be higher than others, it would receive less force).

phuvinh1408
Halfling
Posts: 45
Joined: Tue Aug 09, 2022 7:55 am
x 1

Re: I am new in Ogre and shader, and need some help with wind control on a tree branch

Post by phuvinh1408 »

rpgplayerrobin wrote: Wed May 31, 2023 1:35 pm

I think this approach is too naive, because since you cannot know the direction of the current branch.
That means that the main branch, which would normally stay completely still in the wind, would also be affected by the shader.

Also, I don't get why the UV would change just because of the wind. That does not make sense. Only the vertices positions/tangents/normals should move.

If that main branch would always be in the middle and not be bent in any way, you could get the x/z coordinates and see if they are further from the middle, and then multiply the wind value with the distance from the middle (making branches further away get affected by the wind more), but you can also clamp it of course (the only point here is so the main branch does not get affected by the wind).

But if the main branch is a bit bent, you will have a tougher time to do this only in a shader.
If you want to have full control over this, I would implement it in a skeleton instead.
That way, you can move the bones in code to simulate the wind instead. This could also later be expanded to having physics based elements on the tree (like dynamic forces, like an explosion nearby would also affect the tree).
This physics based solution would also make it possible to have different mass of each bone, which would make the main branch being able to move as well, but it would behave like it would be much harder to move (like the explosion would move the entire trees bones, but since the mass of one bone would be higher than others, it would receive less force).

so you mean I should create a physical skeleton for both tree and branches right. And with this I can animate the branches with the key frame to look like the wind is blowing through without interference from the shader right?

But if I have to do this, it will increase the size of my file because I have to carry more skeleton files, and if I have many different types of trees, time is a big problem for skeletonization each type. I'm new to ogre and shaders so there are still a few things that I don't quite understand. I have some mesh files related to grass and in this file the Vertex part that I see there appear 2 texcoords on 1 vertex, and 1 of those texcoords x ,y ,z values will change, and I think that what you're talking about is the direction to change. If I can post my tree vertex structure can you help me find a solution for my shader, because I want to use 1 shader to control the branches for all the different trees instead. since skeleton like the classic way, as my application need to save space as small as possible I hope there will be a suitable way.

If there's something I still don't understand, please don't be sad, because I'm new in this field. Thank you.

rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: I am new in Ogre and shader, and need some help with wind control on a tree branch

Post by rpgplayerrobin »

so you mean I should create a physical skeleton for both tree and branches right. And with this I can animate the branches with the key frame to look like the wind is blowing through without interference from the shader right?

You could do that, yeah, if you want a constant wind.
The good thing about that approach is that you can get exactly the results you want.

You could also instead not animate it at all and add physical objects (like BulletPhysics spheres) on each bone with constraints, and then move the bones of the tree with those physical objects.
That way, you can code the wind in C++ instead, which would move the physical objects, which also in turn then would move the tree.
But of course, this way is not at all optimized for many trees at a time, I would say maybe 30 trees using this is OK, otherwise it is probably pretty slow because of the physics part.

But if I have to do this, it will increase the size of my file because I have to carry more skeleton files, and if I have many different types of trees, time is a big problem for skeletonization each type.

I am not sure that the increase in size and an additional skeleton file would take that much time to load in. The bottleneck in Ogre that I have experienced is mostly shader compilation. Without shader compilation, my game loads in 3-4 seconds.
If I compile all shaders each startup without any sort of threading it would take 25 seconds to load the game with around 50 shaders.
With threading, it goes down to in total only take 7-8 seconds to start the game, which pretty much proves that shader compilation will be your bottleneck (since threading shader compilation is impossible to do in 1.7 without major code changes).
So I would not worry to have even 100 meshes and skeletons. And you will only need at most 10 different trees, right?

I'm new to ogre and shaders so there are still a few things that I don't quite understand. I have some mesh files related to grass and in this file the Vertex part that I see there appear 2 texcoords on 1 vertex, and 1 of those texcoords x ,y ,z values will change, and I think that what you're talking about is the direction to change.

This is confusing.
What have you put on the UV 2 (texture coordinate 2) part on each vertex for the mesh file?
I don't see it used anywhere in the shader, only UV 1 is used.

Also, the wind should never alter the UV, only the vertices, but that is not done in your shader (which should be in the vertex shader).

If I can post my tree vertex structure can you help me find a solution for my shader, because I want to use 1 shader to control the branches for all the different trees instead. since skeleton like the classic way, as my application need to save space as small as possible I hope there will be a suitable way.

There is not much I can do even if I get the mesh.
It might be hard to do without doing an advanced system.
But here is another idea:

  • In your 3D modelling program, for each vertex, set its texture coordinate 2 (UV 2) to a value between 0 and 1 in its x coordinate (don't care about the y coordinate).
    0 means that no wind will be used for that vertex, and 1 means that the wind will have full effect.
    So put 0 at the main tree branch, which should probably never be affected by wind (or at least maybe just 0.1, but 0 at the root of course).
    Then, for each branch, at the start of the branch it should have the same value as the base has (so if your main tree branch that touches that branch has 0.1, start at 0.1), and then it should go out towards the end of the branch and be 1.
    You would have to do this for each vertex, so try to get a nice interpolation all the way to 1 at the end of each branch.

  • In your shader, send in the wind direction and the wind strength (two uniforms, probably float3 windDirection, float windStrength).
    Then, for each vertex, you would fetch UV 2 and alter the vertex position by something like this: pos += windDirection * windStrength * uv2Value;
    If you have dynamic control over windStrength, you can visualize how the tree would look if it had full wind strength on it and control if each vertex looks as it should.
    Then you could add a sin/cos that alters the position over time, like this: pos.xy += float2(sin(time * windStrength), cos(time * windStrength)) * randomMovementSpeed * uv2Value;
    The variable randomMovementSpeed would have to be defined to something like: const float randomMovementSpeed = 0.5;
    But that variable has to be adjusted of course to make it look better.
    The fragment shader would just return the color, not change anything in the UV or anything like it does currently.

This may cause the tree to at least look somewhat better than just moving the entire tree with the same values.

vincentdoan86
Gnoblar
Posts: 3
Joined: Wed May 31, 2023 4:11 am

Re: I am new in Ogre and shader, and need some help with wind control on a tree branch

Post by vincentdoan86 »

I discovered the problem, If I unpack my mesh file with OgreXLMConverter and then repack it with OgreXMLConverter, my shader can't get UV2 from this mesh file, I don't know if it's because the packing structure is different or not but that is caused because in my mesh file declared UV(Texcoord) coordinates. The convert tool will pack to version v100, but my file structure when exporting the file is only used in v1.40, I don't know how to do it even though I used the Upgrader tool to downgrade the version, but the structure is still the same so it's still the structure of version v100.

I think the tool export a different binary, so that is why cause the problem

Last edited by vincentdoan86 on Fri Jun 02, 2023 3:10 am, edited 1 time in total.
User avatar
sercero
Bronze Sponsor
Bronze Sponsor
Posts: 449
Joined: Sun Jan 18, 2015 4:20 pm
Location: Buenos Aires, Argentina
x 156

Re: I am new in Ogre and shader, and need some help with wind control on a tree branch

Post by sercero »

I don't know if it is a good idea to use bones for the trees since that might be using a lot of resources for something the player will probably not pay much attention to.

It is common practice to use a shader that moves the tree and has the strength modulated by the height (so the branches are more affected than the trunk). That is a cheap way to simulate wind.

rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: I am new in Ogre and shader, and need some help with wind control on a tree branch

Post by rpgplayerrobin »

I don't know if it is a good idea to use bones for the trees since that might be using a lot of resources for something the player will probably not pay much attention to.

It is common practice to use a shader that moves the tree and has the strength modulated by the height (so the branches are more affected than the trunk). That is a cheap way to simulate wind.

That is correct, but if you want more than just static wind elements, with actually having branches and leaves and such behave correctly when a big explosion or something like the player does collides with them, doing it with bones is pretty smart.

That is also what I use in my game, and with 1000+ objects using that approach does not do anything to my performance since most of them are "sleeping" in the physics engine (BulletPhysics).
In my game, not creating those physical objects compared to creating them has almost no impact on performance.
It only takes a bit performance when they are actually in use, and depending on the game (top-down view for me) you can get away with just having a few objects updating their physical objects on the screen.

But it does take more time to do it this way of course, and it is very important to know and understand how to optimize it.

Post Reply