Hi at all!
I was recently messing around quite a lot with grass scripts and their performance. Unfortunately, none of the scripts I was able to find on these forums or to create by myself seemed to be fast enough. So I thought 'why not use one big grass model instead of hundreds'?
I must say it turned out to be a complete success regarding speed, although this method is a tiny little bit harder to implement. Here's what I do, anyway.
EDIT: Get the comfortable version (customizable via WED) -
click here! Copy and paste the following into your script:define highest_vertex,skill1;
define lowest_vertex,skill2;
material mat_vegetation
{
//whatever material definitions go here
effect = "
dword mtlSkill1;
texture mtlSkin1;
technique alphaTestMaterial{
pass p0{
zWriteEnable=true;
AlphaBlendEnable=true;
alphaTestEnable=true;
AlphaFunc=greater;
AlphaRef=<mtlSkill1>;
cullMode=ccw;}}
technique fallback{pass p0{}}";
}
//uses: highest_vertex lowest_vertex
action vegetation_
{
var i;
var maxVerts; //used to store the total number of vertices in the model
var height;
var current[3]; //used to store the current position of a vertex
var new[3]; //used to store the new (i.e. target) position of a vertex
var old[3]; //like current, but contains global instead of local coordinates
my.material = mat_vegetation; //assign a material
my.invisible = 1; //make the whole thingy invisible so one cannot watch the grass deform
my.transparent = 1;
my.flare = 0;
my.passable = 1;
maxVerts = ent_vertices(my) + 1; //this makes sure every vertex in the model is processed
height = my.highest_vertex - my.lowest_vertex; //calculate the height of the model from the coords of the lowest/highest vertex
while(i < maxVerts)
{
//calculate vertex positions (vec_for_vertex is used for global, vec_for_mesh for local coords)
vec_for_vertex(old,my,i);
vec_for_vertex(temp,my,i);
vec_for_mesh(new,my,i);
vec_for_mesh(current,my,i);
//scan 5000 quants down
temp.z -= 5000;
//if this is one of the bottom vertices
if(int(current.z) == my.lowest_vertex){
//lower it to the ground by tracing down
new.z -= c_trace(old,temp,ignore_me+ignore_sprites+ignore_passable);
vec_to_mesh(new,me,i);}
//if this is one of the top vertices
if(int(current.z) == my.highest_vertex){
//lower it to the ground but add the model height
new.z -= c_trace(old,temp,ignore_me+ignore_sprites+ignore_passable) - height;
//finally randomly in-/decrease the z coords of the vertex to make this look more interesting
new.z += (random(40) - 20);
vec_to_mesh(new,me,i);}
//finally, increment i
i += 1;
}
//when done, switch invisibility off
my.invisible = 0;
}
Now assign the "vegetation_" action to your grass model.
Make sure that:- The grass model's top is a plane, i.e. no single bushes or things like that should be higher or less high than the others. Basically, the model has to look like this: Click here
- The grass model is not too big (you've got to mess around with this a bit in order to find out how your graphics card will deal with it) - even with this method, use multiple models (3 will be satisfying for a rather small level I guess).
Now open your grass model in MED, zoom as close as possible and move your mouse over the highest vertex of the model. Keep the mouse there and have a look at MED's status line at the very bottom of the program. The fourth box from the right indicates the mouse's z-position. Put the integer part of what you see there into the action's skill1 (highest_vertex). Do the same for the lowest vertex of the model and skill2 (lowest_vertex).
Hope this helps someone
If anything doesn't work or behave the way it should, please let me know!