The POV-Ray Cyclopedia

When I was working on an entry for the IRTC topic Ruins, I decided I needed some grass. So I spent a couple of days playing with my bezier.inc file and came up with this.

Note 3-13-03: Updated Grasspatch to work with POV-Ray 3.5.

Download grasspatch.inc here
Download bezier.inc here
Download the Grasspatch Template file for Mac
Click here for instructions
Download the Grasspatch Template file for Windows

Part Zero
Setting up the basics

You will need bezier.inc to use grasspatch.inc., just a warning

You can include grasspatch.inc at the beginning of a file, and if you have already included bezier.inc, all the better. If you haven't it will include bezier.inc for you. A standard I use is to declare HelloWhatever at the beginning of an include file. When you include grasspatch, it checks if HelloBezier is defined, and if it is, it move on, otherwise it will include the file. Maybe this is paranoia on my part, but including some files multiple times can ask for trouble as far as I know, or at least make you use more memory than you should during parsing of a scene.

Now there are three basic Patch types available:

  • 0: Circle
  • 1: Square
  • 2: Polygon
  • 3: The Curving Path Patch

Lets play with the settings for the blades of grass.

// Blade_Heights are in standard POV units
#declare Blade_Height_Minimum = 1.75;
#declare Blade_Height_Maximum = 3;

// Some random number generators, you may change these if you wish
#declare someseed = seed(2345);
#declare xseed = seed(42);
#declare zseed = seed(369);

#declare Patch_Tranlation = <0,0,0>;
// Sometimes it's handy just to see where the blades will be
// so we set PlotPoints to true, by default it is
#declare PlotPoints = false;

// per unit length. Square this to know how many will be in each
// unit squared of landscape
#declare Blade_Density = 2; 

// And of course the texture. This is the default:
#declare Blade_Tex = 
  texture { pigment { rgb <0,0.3,0> } 
            finish { phong 0.25 ambient 0.2 } }

Some of these should be self_explanatory, the hieght of each blade will range from Blade_Height_Minimum to Blade_Height_Maximum, and if you want to change the random number seeds, feel free to. These are the three I use here.

Patch_Translation is a vector that will move every blade in a uniform manner. Plot Points replaces blades of grass with small spheres, just so you can get a feel of where the patch is on the ground. By default this is off. Blade_Density control how many blades appear in one POV unit along each axis, so if your Blade_Density is two, you will have four blades on each unit squared (this is the average amount, of course). And the texture is a simple dark green with some ambient applied to keep the shadows from overwhelming the grass. This is the only way POV-Ray can counteract a shadow, but it would mess up radiosity quite a bit, I'm sure

Part One
Detailing circular patches

To create a circular clump of grass there isn't much that we have to do.

#declare Patch_Shape = 0; // Circular

#declare Clump_Radius_Minimum = 0;
#declare Clump_Radius_Maximum = 2;

All that is left is to run the macro, which I have called

PlantPatch()
And this is all it took to make image 1.

You may notice that the blades are concentrated in the center and this can be corrected by adjusting Spread_Correction:

#declare Spread_Correction = 0.5;
PlantPatch()
The closer to zero, the greater the tendency to place the blades close to Clump_Radius_Maximum. The higher it is, the greater the tendency to place the blades cose to Clump_Radius_Minimum. As you can see, setting it to 0.5 gives us better distribution, as in image 2.

And of course to make a ring we simply declare Clump_Radius_Minimum to be something greater than zero:

#declare Clump_Radius_Minimum = 1;
PlantPatch() 
Which gave us image 3.

Circular clump
1. A Simple Circular Clump
Circular clump
2. Better Distribution
Circular clump
3. Ring of grass?
Part Two
The Square Patch

The square field has a few different properties. It will lie on a grid on the x-z plane.

#declare Patch_Shape = 1; // Square
#declare Patch_X_Minimum = -2;
#declare Patch_X_Maximum = 2;

#declare Patch_Z_Minimum = -2;
#declare Patch_Z_Maximum = 2;

PlantPatch()
And we have image 4. This distribution method should prevent large areas from being empty and it covers the ground quite nicely.

Circular clump
4. Normal Square Plot
Part Three
The Polygon Patch
The Polygon patch is loads of fun, but version 1.0 of grasspatch.inc doesn't do the greatest job of making it look like a rigid polygon. In fact, the shapes aren't rigid polygons, but because ofthat we can make slightly more complex shapes:
#declare Patch_Shape = 2; // Polygon
#declare Clump_Radius_Minimum = 0;
#declare Clump_Radius_Maximum = 2;
#declare Patch_Sides = 3;
#declare Poly_Radius_Range = 0.333;

PlantPatch()
This is the code for image 5. Poly_Radius_Range works by reducing the radius of the patch by a certain amount, dependant on the angle. If it is set to 1 the sides will be sucked into the center of the polygon. If it is set to 0 you will end up with a circular patch. Setting it to a negative number will create cloverleaf type shapes as well. This is adjusted by Clump_Radius_Maximum.

Some recomendations for "straight" edges:

  • triangle : 0.333
  • square : 0.25
  • pentagon : 0.15
  • hexagon : 0.1
  • heptagon : 0.08
  • octagon : 0.075
  • enneagon : 0.065

Of course, with semi-regular polygons you will want to, on occaison, to rotate the patch, so declare

#declare RadialOffset = 0;
The default is zero and this is strict rotation around the y axis.

Just for fun, lets play with some settings:

#declare someseed = seed(1653);
#declare Patch_Sides = 5;
#declare Blade_Density = 3;
#declare Spread_Correction = 0.25;
#declare Poly_Radius_Range = 0.75;
PlantPatch() 
And we have image 6.
Circular clump
5. A triangular patch
Circular clump
6. A starry patch
Part Four
The Curving Path Patch

The Curving Path Patch relies on declaring a spline with bezier.inc. It ignores the y component of the path, and deals only with the x and y components. For the image I used a smaller Clump_Radius_Maximum to focus the blades closer to the spline.

#declare Patch_Shape = 3;

#declare Patch_Path = array[4] { <-3,0,0>, <-1,0,5>, <1,0,-5> <3,0,0> }
#declare Path_Density = 6;
#declare Path_Points = 20;

#declare Clump_Radius_Maximum = 0.75;

PlantPatch() 
And we have image 7. The id of the spline has to 'Patch_Path.' You can preview the spline with :
DrawSpline(Patch_Path)
Path_Density works differently than Blade_Density. Path_Density tells grasspatch.inc to find that many points at each point along the path. The number of points is determined by Path_Points.

Circular clump
7. A Path Patch
Part Five
Blade Details

The blades of grass can now be customized to some extent. The curve has been made more natural and the width is now customizable. There file will also allow you to reduce the detail of the blades as they get further away from the camera.

#declare Use_Blade_Distance = true;
#declare Blade_Detail = 10;
#declare Max_Blade_Angle = 45;
#declare Min_Blade_Angle = 10;

#declare Blade_Scale = 1;
#declare Blade_Width = 0.075;

#declare Use_Blade_Distance = true;
#declare Camera_Position = <0,0,-4>;
#declare Max_Blade_Detail = 20;
#declare Min_Blade_Detail = 5;
#declare Max_Detail_Distance = 1;
#declare Min_Detail_Distance = 10;

Use_Blade_Distance toggles whether or not you use detail loss at a greater distance or not. If Use_Blade_Distance is true, then Max_Blade_Angle and Min_Blade_Angle are used. If Use_Blade_Distance is false, then Blade_Detail is used uniformly on all the blades. The blades are contrained in a cone_shape, the angle from the central height to the side are dictated by Max_Blade_Angle and Min_Blade_Angle. Since this is hard to describe, image 8 hopefully tells the story well.

Blade_Scale allows you to alter the entire scale of the blade. It's a global change since grasspatch.inc assumes 1 unit = 1 inch. You'll want to change that to 1/12 if 1 unit = 1 foot in your scene. Blade_Width allows you to alter the width of the blade to some extent. The default is 0.075 which can make a thinner blade. Image 9 shows two blades, one with width 0.075 and one with width 0.25.

The next few declarations involve a potentially time saving device. Blades of grass that have a lot of detail to the curve are useful when they are close to the camera, but when they are far away they don't need to be as detailed, so if we calculate fewer points, we get fewer triangles, less parse time, and a faster render. You don't have to use this feature, so you can turn it off by declaring Use_Blade_Distance = false. You will need to declare Camera_Position to be the camera location point. (It doesn't really have to be, but the effect is more practical when they are the same.) and Max_Blade_Detail and Min_Blade_Detail, as well as Max_Detail_Distance and Min_Detail_Distance. At Max_Detail_Distance the blades will have Max_Detail_Distance. The detail will decrease until the distance between the blade and the camera position is equal to Min_Detail_Distance. At this point and whenever the distance is greater than that, the blade will have Min_Blade_Detail.

blade angles illustrated
8. Blade Angles Illustrated
thin blade fat blade
9. Two blades

Send feedback, or head back to the Cyclopedia.

Thanks for watching.

��� ��� ��� ��� ���