Need wind effect for tree models

Anyone know a good way to implement wind effects on models?? What I have is a model of a trees which is loaded then a bunch of shared nodes are created to build a forest. My question is how would I implement a wind effect on this forest?? I did a search but only found examples on the CollidingClothPatch is there a way to add this effect to any model??

How about a vertex shader? However in case of shared node they will all appear the same.(due to same shader state) Idea is, load each tree like 5 times, and apply the shader witha  different internal time, this way not every tree looks and mooves exactly like the others, while still having most of the benefits from a shared node.

You can change the shader parameters for even shared nodes. If you use GLSLShaderLogic. This would allow you to animate the trees as SharedNode with a vertex shader.

Perhaps you could fake it and animate your models? One way would be to use a tool like Blender to add a skeletal structure (“bones”) to the trees and move them. The wiki has a tutorial on how to do this.



If you need something more realistic then it’s probably time to start looking at a physics engine.

thanks for the tips … is there an example I could have a look at for this vertex shader, I've looked but no luck.

Well you probably have to learn the glsl language (and i will need to do this soon to :/)

O.M.G not another language … lol, at this moment I'm trying to work with a physics implementation rather than shaders but I'm having trouble getting any of the physics to show … I'm wondering if it has something to do with me using GameStates??

To be honest, it would probably be easier learning GLSL. Besides it's good to know since so much today is shader based. And really it's not all that hard, especially if you have some background in C. All the usual high level shader languages (GLSL, Cg, HLSL) are more or less C-based.

ok, where should I start??

Look at something like this:

http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter01.html

The trunk and primary branches of a tree should be modeled as 3D meshes. Secondary branches can be simulated with billboards to add visual complexity. For trees that are leafy, we can use techniques similar to the one we used for grass to create clumps of leaves from camera-facing billboards.

thanks I'll have a look … seems like alot to read … lol, but I like to read so I dig right in. Also my tree modles are full 3d trees … trunk, branches, leaves are all 3d meshes.

Shaders aren't the simplest thing to do, mind you. So I wouldn't recommend them to anyone just starting with 3D engines and the like. If you can animate the tree model in your modeling tool then export it to one of the animation-supporting formats it would probably be a lot easier.

ok, in my endeavor to learn shaders I found a wobble shader which I believe could be used to simulate wind blowing against a model, but something seems to be wrong … I've done all the google searches I can do and followed all the examples for loading the shader … here is what I have so fare …



in my forest class I add all the trees I need at any given point on the terrain … keep in mind these models are all SharedNodes, after setting up the model and adding it to the scene I do this …


 so.load(MainApp.class.getClassLoader().getResource("glsl/CH16-wobble.vert.txt"),
MainApp.class.getClassLoader().getResource("glsl/CH16-wobble.frag.txt"));
so.clearUniforms();
so.setUniform("LightPosition", new Vector3f(-30f, 50f, -185f));
so.setUniform("StartRad", 5.0f);
so.setUniform("Freq", new Vector2f(-30f , 50f));
so.setUniform("Amplitude", new Vector2f(-30f, 50f ));
so.setUniform("WobbleTex", 0); // this is sopposed to be my leave texure
so.setEnabled(true);




I start the app and everything but the trees is ok ... the trees are rendered black rather than the green leafy texture I have loaded ... and there is no wobble ... any ideas?? As I said before I am using gamestates should I put all the glsl setup in the gamestate itslef or is it ok in the class that builds the forest?? should anything from the glsl go into an update or render methode??



here is the shaders ...

vert

//
// Vertex shader for wobbling a texture
//
// Author: Antonio Tejada
//
// Copyright (c) 2002-2005 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//

varying float LightIntensity;
uniform vec3 LightPosition;

const float specularContribution = 0.1;
const float diffuseContribution  = 1.0 - specularContribution;

void main()
{
    vec3 ecPosition = vec3 (gl_ModelViewMatrix * gl_Vertex);
    vec3 tnorm      = normalize(gl_NormalMatrix * gl_Normal);
    vec3 lightVec   = normalize(LightPosition - ecPosition);
    vec3 reflectVec = reflect(-lightVec, tnorm);
    vec3 viewVec    = normalize(-ecPosition);

    float spec      = clamp(dot(reflectVec, viewVec), 0.0, 1.0);
    spec            = pow(spec, 16.0);

    LightIntensity  = diffuseContribution * max(dot(lightVec, tnorm), 0.0)
                      + specularContribution * spec;

    gl_TexCoord[0]  = gl_MultiTexCoord0;
    gl_Position     = ftransform();
}



and the frag ...

//
// Fragment shader for wobbling a texture
//
// Author: Antonio Tejada
//
// Copyright (c) 2002-2005 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//

// Constants
const float C_PI    = 3.1415;
const float C_2PI   = 2.0 * C_PI;
const float C_2PI_I = 1.0 / (2.0 * C_PI);
const float C_PI_2  = C_PI / 2.0;

varying float LightIntensity;

uniform float StartRad;
uniform vec2  Freq;
uniform vec2  Amplitude;

uniform sampler2D WobbleTex;

void main()
{
    vec2  perturb;
    float rad;
    vec3  color;

    // Compute a perturbation factor for the x-direction
    rad = (gl_TexCoord[0].s + gl_TexCoord[0].t - 1.0 + StartRad) * Freq.x;

    // Wrap to -2.0*PI, 2*PI
    rad = rad * C_2PI_I;
    rad = fract(rad);
    rad = rad * C_2PI;

    // Center in -PI, PI
    if (rad >  C_PI) rad = rad - C_2PI;
    if (rad < -C_PI) rad = rad + C_2PI;

    // Center in -PI/2, PI/2
    if (rad >  C_PI_2) rad =  C_PI - rad;
    if (rad < -C_PI_2) rad = -C_PI - rad;

    perturb.x  = (rad - (rad * rad * rad / 6.0)) * Amplitude.x;

    // Now compute a perturbation factor for the y-direction
    rad = (gl_TexCoord[0].s - gl_TexCoord[0].t + StartRad) * Freq.y;

    // Wrap to -2*PI, 2*PI
    rad = rad * C_2PI_I;
    rad = fract(rad);
    rad = rad * C_2PI;

    // Center in -PI, PI
    if (rad >  C_PI) rad = rad - C_2PI;
    if (rad < -C_PI) rad = rad + C_2PI;

    // Center in -PI/2, PI/2
    if (rad >  C_PI_2) rad =  C_PI - rad;
    if (rad < -C_PI_2) rad = -C_PI - rad;

    perturb.y  = (rad - (rad * rad * rad / 6.0)) * Amplitude.y;

    color = vec3(texture2D(WobbleTex, perturb + gl_TexCoord[0].st));

    gl_FragColor = vec4(color * LightIntensity, 1.0);
}

Like I said, shaders are not for the faint of the heart… You need to actually understand how they work and what each thing does to get the desired result. Anyway, what this wobble shader does is not what you want. It wobbles the texture on the model which won't be anything close to wind.

The intended result can only be achieved in the vertex shader, since it allows you to deform the model. Once the wind function is defined, you need to apply the wind offset to gl_Vertex as you set it into gl_Position. Also note that you will be limited to only 1 light on your tree models unless you use multipass or something else.

I wonder, why is there a limitation to one light if the shader is in the same pass?

Empire Phoenix said:

I wonder, why is there a limitation to one light if the shader is in the same pass?

There isn't, but generally it is more difficult to do more than 1 light in shader, it needs things to be handled differently. Compare the shaders per_light and phong_lighting in jME3 to see why it's different. Also shaders supporting more than 1 light are not compatible with PS2.0/GLSL1.0