Wind in the trees

Jules Robichaud Gagnon

27-05-2008 18:27:16

Hi JohnJ,

I was wondering if it was thinkable to add some minor wind effect on the trees with the paged geometry and how it could be implemented.

I thought of adding the original position of the tree in the vertex declaration of the vertices. That way each tree could be deformed according to his original position in the vertex shader.

Share your thoughts.


Jules Robichaud Gagnon


28-05-2008 16:11:12

Yeah, I haven't actually tried a wind effect on trees, but I had some ideas I plan on trying some day. One idea was to simply ripple leaf vertexes similar to the way grass is swayed, only add a small per-vertex sway factor value so leaf vertexes connected or near a branch will stay still (attached to the branch). The sway factor values could possibly be done in a modeler through vertex colors, and then converted to something else so they don't interfere with real vertex colors used with lightmaps.

Of course I haven't really thought this out very much, I'm not sure if there are any hidden drawbacks or issues with this method, although it seems fairly straightforward and probably would work very well for slight wind effects.

Jules Robichaud Gagnon

28-05-2008 16:44:48

We will have an internship soon and we will have the person to work on this.

I'd like to discuss of your ideas.


28-05-2008 16:59:32

Well I'll be happy to discuss any ideas on the subject, although beyond the technique I just described, I haven't thought this out that much so far :). I'll think about it a little more, since I plan to integrate an effect like this in PagedGeometry 2.0 (or whatever).


07-06-2008 02:29:14

Hi, I'm the intern working with Jules on this shader. We managed to get a really nice effect already.
Here's what we got so far

Enjoy ^^


07-06-2008 04:39:40

Nice! :D. Good to see you're making progress, it looks great :).

Out of curiosity, was the technique I talked about with Jules any help?

Thanks for posting the video, and keep up the good work!

Jules Robichaud Gagnon

07-06-2008 15:38:29

For the moment, all the calculations are made from the original position of the vertex. We save the vertex position with rotation and scale transformation into a texture coordinate. Loup had the great idea to make the movement in two directions. The leaning forward is proportional to the height of the tree and the movement up and down of the branches is proportional to the distance from the middle of the tree. It looks very natural.

She hasn't implemented the tool assisted weighted sum (putting coefficient in texture coordinate in modeling tool) yet and I wonder if it is necessary since all the information we used to do this was available on the fly when copying the trees in the batches.

The best is to keep it simple and light weight. If we can do it only with a serie of "if"s, it is much less complicated than having to provide a custom mesh. The second technique could be a Wind Advanced mode for extra tweaking.


07-06-2008 17:38:31

The leaning forward is proportional to the height of the tree and the movement up and down of the branches is proportional to the distance from the middle of the tree.
That's very good idea, and the technique fits perfectly with the type of trees you're using.

It sounds like there's really no need for the weight system I described then at least for the types of trees you're using. The weights would mainly help fake the effect of a bone per branch, which would only be useful with large trees with many levels of hierarchal branches.

Like you say, if possible it's much nicer to not have to edit custom animation info in an editor when it can all be done in the shader.

Jules Robichaud Gagnon

09-06-2008 16:08:11

Loup is adding a method setCustomParam and getCustomParam to PagedGeometry where we can specify global parameters or per-entity parameters. Those parameters will be stored in a map in the paged geometry.

We will use this to add parameters to customize wind in the trees per entity.

I think it is the easiest way to do this.


09-06-2008 16:31:29

Sounds like a good solution, though it may not be the most efficient. I just now took a look at Ogre::Material's documentation, and found getParameter() and setParamater() functions. I don't know if this is for general user data, or for Ogre-specific values, but you might look into it as a possible easier / better solution.


10-06-2008 17:55:09

My parameter functions are working but I'm stuck with quite a strange bug. I'm trying to apply different custom parameters for the shader to the trees and the bushes but it doesn't work correctly if there is more than one entity in the same PagedGeometry. In that case, it will only consider the parameters from the last entity and apply it to all entities of this PagedGeometry.

I used exemple 8 for this :
in World::load() , where the bushes are created, I added the following setCustomParam lines
Entity *fern = sceneMgr->createEntity("Fern", "farn1.mesh");
bushes->setCustomParam(fern->getName(), "factorX", 0);

Entity *plant = sceneMgr->createEntity("Plant", "plant2.mesh");
bushes->setCustomParam(plant->getName(), "factorX", 1000);

Entity *mushroom = sceneMgr->createEntity("Mushroom", "shroom1_1.mesh");
bushes->setCustomParam(mushroom->getName(), "factorX", 1);

Normally, every entity of bushes should move differently but it seems to randomly select one of the 3 and apply its parameter to the others, though I've yet to see the fern one being used... :?

I created a custom parameter in BatchPage to pass the value to the shader, at the same place as the others in BatchPage::_updateShaders() :
params->setNamedAutoConstant("factorX", GpuProgramParameters::ACT_CUSTOM);
params->setNamedConstant("factorX", mGeom->getCustomParam( entityName, "factorX", 0 )); // returns a float

The problem is that it seems only one entity per PagedGeometry pass throught there, meaning the others don't have their parameter sent to the shader. I know the map is filled correctly and the values passed correctly to the shader, it's just they are not all passed :?

I was hoping you might have an idea why it acts this way ( I hope my description is clear enough). I'm currently going through the whole code to find where this happens but if you have any hint, it would be appreciated.

edit : The get and setCustomParam are defined in PagedGeometry. The entityName variable is a string member I added to BatchPage to keep the name of the current entity used. mGeom is also a member added to BatchPage and keeps a pointer to the PagedGeometry used. It is used to get access to the parameter map that is in the PagedGeometry class. The key in the map is created with entityName.paramName. For example, in this case we would have "plant.factorX".

Jules Robichaud Gagnon

11-06-2008 01:41:44

Hey JohnJ shouldn't GpuProgramParameters::ACT_CUSTOM be used only with Ogre::Renderable::setCustomParameter ? Maybe it does not have the behaviours we expect it to have.

A while ago, I used the setCustomParameter to solve a problem I had with the scroll animation shader of the snowmobile's track because in multiplayer they were all using the same parameter since it was set directly in the shader/material. All the tracks were scrolling at the speed of the last snowmobile. Maybe something similar is happening here with setNamedConstant.

/// A custom parameter which will come from the renderable, using 'data' as the identifier

/** Sets a custom parameter for this Renderable, which may be used to
drive calculations for this specific Renderable, like GPU program parameters.
Calling this method simply associates a numeric index with a 4-dimensional
value for this specific Renderable. This is most useful if the material
which this Renderable uses a vertex or fragment program, and has an
ACT_CUSTOM parameter entry. This parameter entry can refer to the
index you specify as part of this call, thereby mapping a custom
parameter for this renderable to a program parameter.
@param index The index with which to associate the value. Note that this
does not have to start at 0, and can include gaps. It also has no direct
correlation with a GPU program parameter index - the mapping between the
two is performed by the ACT_CUSTOM entry, if that is used.
@param value The value to associate.
void setCustomParameter(size_t index, const Vector4& value)
mCustomParameters[index] = value;

From Ogre's reference guide
This allows you to map a custom parameter on an individual Renderable (see Renderable::setCustomParameter) to a parameter on a GPU program. It requires that you complete the 'extra_params' field with the index that was used in the Renderable::setCustomParameter call, and this will ensure that whenever this Renderable is used, it will have it's custom parameter mapped in. It's very important that this parameter has been defined on all Renderables that are assigned the material that contains this automatic mapping, otherwise the process will fail.


11-06-2008 02:37:36

I think the problem Loup is having is that the custom parameters are being applied to an entire batch / material set rather than on a per-tree basis. I actually still don't know how to apply individual custom shader parameters on a per-renderable basis in Ogre (though it sounds like you figured it out), but even if I did the problem would remain. Here's why:

When you use BatchPage in PagedGeometry for your trees, remember that it's "batching" your trees, and therefore an entire group of trees is going to be one renderable. Unfortunately, this means that there is no way you're going to apply custom vertex shader parameters per tree. Even if you could, it would defeat the purpose of batching.

So unless I'm totally misunderstanding the problem, you're probably going to have to figure out a batch-friendly way of providing per-tree properties, whether it be including the data in the per-vertex data, or some more advanced method with the shader.


11-06-2008 13:56:49

In fact, we want the trees of the same batch to have the same parameter. The problem here is that if I create more than one type of tree or, in the example a plant, a fern and a mushroom and they are all inside the same PagedGeometry (in this case "bushes"), they'll all have the same parameter.

I will try to apply what Jules said this morning and update you later today.

Jules Robichaud Gagnon

13-06-2008 01:32:01

I figured out what was the problem, it was only the name of the entity that was set at the wrong place so it was using the value of the last item added, sniff. I had just the time to check deeply what was happening.

This had nothing to do with the ACT_CUSTOM like i thought at first.

We should provide a first patch real soon, Loup will clean the code up tomorrow.

Jules Robichaud Gagnon

13-06-2008 15:55:55

I realized that if we want the parameters to work properly we need to create a SubBatch signature including the Entity name otherwise the parameters will not work properly. The reason is that we sort depending of the material and vertex declaration information. It is normal to gain the maximum effect of the batching. This can cause the trunk to move at the speed of another tree sharing the same material, causing the leaves not to follow the trunk.

The only ways I thought to have parameters per entity in this situation are :
1. To add the parameters into texture coordinates;
2. To sort into different sub batches when using the wind.

It means we will have another extra overhead either way. But the overhead will be noticeable in the second only if we use a lot of identical materials in different entities.

What method do you prefer?


13-06-2008 21:28:49

To summarize what we've talked about through IM:

Supplying the parameters through the texture coordinates will give you better run-time performance, while splitting trees into separate batches (and materials) in order to supply the shader parameters the standard way would be slower during run-time due to the increased batch count, but faster during batching (since there's no extra per-vertex data to upload to the video card).

A third possible alternate would be to somehow "bake" your parameters into existing vertex data. For example now you're using a 3D texture coordinate to store the untransformed positions of the tree's vertices. The shader then takes this position, and computes sway biases, etc. from it. You might be able to precalculate these sway biases, also taking into account the per-tree parameters you refer to, and save them to this 3D texture coordinate instead of the untransformed position values. This would actually be faster than the current method you're using, although trickier to implement.


13-06-2008 22:12:45

Just a note, in the patch, the define are not updated with the new implementation so don't try disabling the BATCHEDGEOMETRY_WIND because I'm not sure it will compile.


13-06-2008 22:14:27

That's fine. I'll probably wait for the updated patch, and in the mean time I'll take a look at the code.

Jules Robichaud Gagnon

17-06-2008 16:56:12

This patch includes the WindBatchPage
with a modified example8 with #ifdef to use wind.

This patch also includes the pagedgeometry.vcproj patch.



18-06-2008 16:43:13

Thanks, I'll try to apply this this evening if I have time. Sorry I didn't have time yesterday.


19-06-2008 16:42:20

The link seems to be dead. Sorry if I waited too long and you had to delete it :(. It's been a busy week here.


19-06-2008 16:48:14

its a lowercase u: .)

Jules Robichaud Gagnon

19-06-2008 18:10:42

its a lowercase u: .)

oUps, thank yoU. I jUst fixed it. ;)


20-06-2008 10:55:48

btw its working great in linux, just had to add the new files to the cmake lists

Jules Robichaud Gagnon

20-06-2008 13:35:32

btw its working great in linux, just had to add the new files to the cmake lists

I am glad it works. Sorry about not adding it to the cmake lists, I have no devel version of linux available. I leave the Linux tests for JohnJ before he adds it to the main version.


20-06-2008 17:53:37

Ok, that works. Thanks.


21-06-2008 15:30:45

Wow.. looks nice. The trees looks more believable now although the existing is great as well. Probably you can add more speed and randomness to the leaves movement to make it even better - bah I can do it myself but this is just a suggestion. :D


21-06-2008 18:58:08

Ok, the patch is applied :). All I did was change "factorX" and "factorY" to "windFactorX" and "windFactorY", and add additional documentation for the added functions / classes.

P.S. Yesterday evening I was accidentally viewing the old patch, rather than the new one, which is why I was still a little worried about unneeded application specific code in PagedGeometry's core objects. I like the new version much better, since all the application specific stuff is properly separated into it's own classes.

Very good job, and thanks again for the donation to PagedGeometry! I've added Wendigo Studios to the credits and also a special thanks to Wendigo Studios in the WindBatchPage documentation.


25-06-2008 16:45:09

For info:
I just updated from SVN and tried to compile:

1>c1xx : fatal error C1083: Cannot open source file: '.\source\WindBatchPage.cpp': No such file or directory
1>c1xx : fatal error C1083: Cannot open source file: '.\source\WindBatchedGeometry.cpp': No such file or directory

Jules Robichaud Gagnon

25-06-2008 17:13:42

Seems like JohnJ forgot to add the new files, I have the same problem. :lol:


26-06-2008 02:53:35

Sorry about that, it should be fixed now.


10-04-2009 03:52:46

Till today, I have run the example8 where wind effect can be applied to tree. However, the wind effect is just a approximate simulation in minor wind. There's only one place to set the wind approximate effection:
#ifdef WIND
trees->setCustomParam(myEntity->getName(), "windFactorX", 30);
trees->setCustomParam(myEntity->getName(), "windFactorY", 0.02);

Through above setting, we cannt simulate the animation in different wind(wind direction and wind force), further more, above setting doesn't indicate the difference of trees in different position. For example, the trees in the front may sway more strongly than the ones in the behind, for the wind go through the front to the behind may minish.

I want to simulate the trees in wind with simplified physical rules, but there's some doubt in mind:
1) if in PagedGeometry(pg for short), is it possible to simulate every tree's wind effect? Of course, to render a forest , instancing (btw, in pg means batch?)technique should be adopted. So, is it possible to simulate every tree's wind effect according to its vertices.
2) when i add my algorithm to pg, which places should be modified?


14-04-2009 15:31:10


Do you have any sources to submit ?
differents link you provided are dead ?

I have just downloaded PagedGeometry system today, and I cannot find this code in the example8 demo
ifdef WIND
trees->setCustomParam(myEntity->getName(), "windFactorX", 30);
trees->setCustomParam(myEntity->getName(), "windFactorY", 0.02);

I am working with Ogre1.6.1 and setCustomParam doesn't seem to exist too.



15-04-2009 01:12:47

you may download the source code of the PG, and you will find it.


15-04-2009 08:50:24

well I did from (the link from the wiki)
I have PageGeometry 1.05 VC8 sources, including PG source and 8 examples, but no "windfactor"


15-04-2009 09:55:16

I get it from the svn.


15-04-2009 09:58:46

so what is the link ?


15-04-2009 11:29:44

ok I've got the sources from the Ogitor forum
but it is not very easy to find...
I have wind in the trees now


16-04-2009 01:09:31

you can get it from with the tool tortoiseSVN.


29-06-2009 11:45:40

you can get it from with the tool tortoiseSVN.
the official svn checkout address is:

thats the most recent code.