In this blog post I will go over my implementation for the third homework task of CENG469 which is Grass Rendering in OpenGL (Geometry Shader, Bezier Curves, Perlin Noise).
Due to time constraints, I could only implement a sort of setup and test scene for this assignment, which is not aesthetically pleasing but contains some basic concept implementations such as bezier curve generation with a geometry shader.
Initial Scene Setup and Grass Point Generation
I have used my previous OpenGL project as the base for this project to utilize the existing camera control mechanisms. Unfortunately there is some amount of unnecessary code left over from the previous project. However, I have implemented all the necessary implementations for grass rendering from scratch.
For the ground where the grass would grow out of, I rendered a brown horizontal quad. I tweaked with an existing cube obj file and left only the face information of the top cube face for this purpose (a lazy solution because I wanted to move on to the next steps of my implementation quickly).
I generated the grass points in my main program. The generation function takes the number of desired grass points and the range where we want to generate them. This range defines the area spanned by the quad. I have hard coded this range for testing purposes.
I have also created a grassShaderProgram to only take vertices and color them green. At this stage there was no geometry shader attached to my program. This is the output I obtained:
 |
30x30 Grass Patch
|
 |
| The same patch viewed from above |
Adding a Simple Geometry Shader
I implemented a geometry shader which takes the grass vertex positions and generates 3 vertices to output triangle strips.
 |
Grass with triangle strips
|
This is the first visual I got that somewhat resembles grass, which was pretty satisfying. To get the triangle strips, I shifted the original vertex position slightly left for vertex one, slightly right for vertex two and up for vertex three to get three new vertices. I haven't emitted the original vertex position.
Generating Bezier Curves
After successfully creating and applying my geometry shader, I needed to change it so that it implements a bezier curve for the grass blade. To first get the bezier curve calculations right, I outputted line strips (as many as the number of bezier segments).
After following the math in our course material for bezier curve implementation in geometry shaders, I obtained the following result:
 |
| Bezier line strips for grass |
Considering a Bezier curve with four points P1, P2, P3, P4, I defined the bottom point of the grass blades as P1 and the top point as P4. P2 is the control point for P1. P3 is the control point for P4. In the image above, P2 and P3 are on the same vertical alignment, slight shifted away from the vertical line that P1 and P4 are on. This is why the line is bent as such.
I brainstormed about what I can use instead of just a line strip for a good looking grass blade. I decided to try generating 2 different line strips for the left and right edges of the grass blade, then filling them in by generating triangle strips between their points.
To obtain this, I defined 2 sets of bezier points. Both lines share the same P4 to meet at the end of the grass blade. Their P1 points are shifted left or right as in the triangle strip generation.
I wanted to have the control points on the line between P4 and P1 because I wanted straight edges for a static, upright grass blade. I tested on a Bezier Curve Simulator (https://www.desmos.com/calculator/cahqdxeshd) to check the correctness of my curve setup logic.
 |
| Curve Simulator and my calculations |
The resulting hollow grass blades:
 |
| Grass blades with 2 Bezier curves |
Bending the Grass Blades
I could not implement wind generation to displace my grass blades, however I tested how the grass blades react to their end points (P4) being displaced. I wanted to change P4 for this simulation, but I wanted the control points to stay at their initial positions because I imagined this would create the desired grass-bending visual. This is the simulator visual of what I wanted to obtain:
As you can see, when only P4 shifts right, the curve bends like a stiff grass blade with wind blowing to the right.
To obtain this effect, I changed the control point calculations to be made with the initial P4 that is aligned with the bottom grass point and does not change. In the curve calculations, I used to updated P4 (shifted right). This is the result I have:
 |
| Bent Bezier grass blades |
Although I didn't get the curve I was expecting, the outline of the grass blades do look quite like bent grass blades (which are perhaps too stiff at the bottom).
Conclusion
This is the end result of my progress for the grass rendering implementation. The next steps I need to follow to improve this implementation are:
- Fix bending grass blade curvature
- Fill in line strips of grass blade
- Add random height variation
- Populate grass patch less uniformly for a more natural look
- Generate more grass for a fuller field look
- Add grass lighting
Even though I couldn't complete the full task implementation, I got to learn and experiment with geometry shaders and Bezier curves. I hope to improve this project in my personal time.
Comments
Post a Comment