CS 280 -- Final Project

Team Composition
Arash Nikkar
Matt Bielejeski
Graphic Techniques Incorporated
The graphics techniques we have chosen to integrate are:
Non-Euler Dynamic Simulation (Springs)
Level of Detail (LoD) representations
Overview
Our project involves a grass field which is affected by blowing wind. This is achieved through a Non-Euler dynamic simulation, by incorporating several
springs within each grass blade and applying an appropriate force in order to simulate the motion caused by blowing wind. Furthermore, we allow the user to
interactively zoom in/out of the picture (scene), during which two different Level of Detail (LoD) filters are applied to the grass field depending on the depth value
of each individual grass blade. One LoD filter applied utilizes the concept of face merging on each individual grass blade. The second filter used involves texture
maps to give the look and feel of of a more realistic grass blades, without having to render them individually.
Our application allows the user to interact with the grass field, by rotating the field, zooming in/out (while applying different levels of detail depending on the depth
value). In addition, we have created a simple to use, yet powerful navigation tool which allows the user to specify the direction and speed of the wind.
Implementation
Non-Euler Dynamic Simulation (Springs)
To simulate realistic movements of grass we implemented a simple spring system which applies forces to the spring and updates the spring with a timestep
using the Simple Harmonic Oscillation equation. To prevent the springs from oscillating infinitely the springs have a simple dampening factor which reduces
the amplitude each iteration until it reaches 0.
The base model of our grass blade has 17 faces and 9 joints. Each joint has two springs, one that moves along the x-axis and one that moves along the y-axis.
This gives a total of 18 springs that are evaluated when a force is applied and until the oscillation stops. The system was designed so as to simplify what to do
when the Level of Detail algorithm causes grass blades to be rendered with fewer faces since this results in fewer joints to move. Each time the level of detail
gets lower fewer springs are evaluated when a force is applied, more specifically only springs that are associated with joints that still exist are evaluated, except
for the lowest detail model which does not get evaluated at all because it only has one joint.
The spring values such as the spring constant and the maximum displacement possible, the frequency of the oscillation and other values needed by the springs
were set by trial and error using some mathematics as a basis for what values to use. The important factor in determining a good value was how far the grass bent
and how long it took to right itself and stop oscillating.
Face Merging (LoD)
Our face merging technique involves merging faces of a grass blade, as its distance from the camera increases. This in turn allows for less triangles to be rendered
for grass blades which are farther away. Thus the level of detail for each individual blade is greatest for those that are closest to the camera, and as each blade's
distance from the camera increases, the number of faces used to draw that face is reduced. As stated in the Springs section the base model for our grass blade is
composed of 17 triangles and our level of detail has 4 levels. Level 0 is the base model with all of its triangles, Level 1 is composed of 9 triangles, Level 2 has 5
triangles and Level 3 has 3 triangles. The idea behind this is that as the camera gets farther away it takes fewer polygons to render the same amount of grass which
is useful since at far distances grass blades map to one or two pixels on the screen so using fewer triangles reduces the load on the Graphics Processing Unit (GPU).
The threshold for each level in the Z direction are as follows:
| Level 0 | 0-2.0 |
| Level 1 | 2.0-2.5 |
| Level 2 | 2.5-3.0 |
| Level 3 | > 3.0 |
Texture Maps (LoD)
As a second and rather simple way of using Level of Detail we applied a grass texture to the grass blades that are rendered at Level 0 so that grass close to the
camera looks more realistic. We thought about using textures to represent multiple blades of grass rendered in the distance however our implementation didn't really
allow us to do this since our grass field is randomly generated it would require texture maps to be created on the fly to get the correct distances between blades.
User Interaction
User interaction is a vital factor of our project, otherwise, the full effect of the grass simulation would not be achieved. Allowing the user to graphically
define the direction and speed of the wind provides a solid approach at viewing the effect the wind places on the grass. As the screenshots (above & below)
indicate, there are yellow x/y axes in the top left hand corner of our grass field model, with a red arrow placed within them. The red arrow is used to indicate
the direction and the speed of the wind. The direction is calculated by subtracting the x & y values at the tip of the red arrow, from the origin of the yellow axes.
Subsequently, the x/y directional values are then applied as forces to the springs within each individual grass blade. The direction is defined by the length of the
red arrow (which is calculated by using the Pythagorean theorem). Thus the longer the red arrow is, the stronger the wind is blowing.
The wind effect is caused by a total of 10 individual wind streams (defined at compile time), where each wind stream is comprised of 10 individual lines (also defined
at compile time). A timer function is called every so often (depending on the length of the red arrow), which then evaluates the wind, and increments the head of the
wind by a constant value in the X direction, and by a value determined by the orientation of the red arrow in the Y direction. Subsequently assigns x/y values of each
line segment to that of the line segment in front of it (or in back of it if the wind is moving in the right --> left direction) which portrays the effect of the wind progressing
forward (or backwards).
Note: By hitting 'p' on the keyboard, or right clicking the mouse and selecting "Picking", the user can click on the red arrow, and drag it around to a desired direction
and speed for the wind. The user must hit 'p', or selecting "Picking" again in order to rotate or zoom the grass field.
Conclusions & Future Work
Our project began as a very challenging one; we tossed around several ideas, and created several implementations before we decided on a solid approach.
Quite a few variations of grass blades were used, varying in the number of faces, and the number of springs used in order to find the desired result. We
intended on implementing a flag blowing in the wind, and implemented several basic versions (including a sine wave simulation), but decided that they did not
provide the desired effect, and we simply did not have enough time to implement a cloth simulation as well.
While we are very proud of our work, we feel that there are several areas that can be improved. Currently, the wind that is displayed is rather simple, and straight
forward. Making the wind look more realistic would be a novel challenge, but worth it. Further improvements can also be achieved in the surroundings of the grass.
It would be much more aesthetically pleasing to draw a whole grass field with dirt representing the ground, rolling hills, and even a light source such as the sun.
We definitely learned a lot in the course of designing and implementing our grass field simulation (most of the learning process was a result of making mistakes).
Resources
Download Source Code (please read README for instructions)
More Screenshots
Wind moving the grass:

Example of how the red arrow defines the direction of the wind.

Our model in Wireframe mode
