University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 6
- LINSHEN XIAO
- Tested on: Windows 10, Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz, 16.0GB, NVIDIA GeForce GTX 970M (Personal computer)
In this project, I used Vulkan to implement a grass simulator and renderer. I used compute shaders to perform physics calculations on Bezier curves that represent individual grass blades. Since rendering every grass blade on every frame will is fairly inefficient, I also use compute shaders to cull grass blades that don't contribute to a given frame. The remaining blades will be passed to a graphics pipeline, in which I wrote several shaders. I wrote a vertex shader to transform Bezier control points, tessellation shaders to dynamically create the grass geometry from the Bezier curves, and a fragment shader to shade the grass blades.
- Compute shader
- Grass pipeline stages
- Vertex shader
- Tessellation control shader
- Tessellation evaluation shader
- Fragment shader
- Simulating Forces
- Gravity
- Recovery
- Wind
- State Validation
- Culling tests
- Orientation
- View-frustum
- Distance
This project is an implementation of the paper, Responsive Real-Time Grass Rendering for General 3D Scenes. The paper does a great job of explaining the key algorithms and math I used. Below is a brief description of the different components in chronological order of how your renderer will execute, but feel free to develop the components in whatever order you prefer.
In this project, grass blades will be represented as Bezier curves while performing physics calculations and culling operations. Each Bezier curve has three control points.
v0: the position of the grass blade on the geomtryv1: a Bezier curve guide that is always "above"v0with respect to the grass blade's up vector (explained soon)v2: a physical guide for which we simulate forces onup: the blade's up vector, which corresponds to the normal of the geometry that the grass blade resides on atv0- Orientation: the orientation of the grass blade's face
- Height: the height of the grass blade
- Width: the width of the grass blade's face
- Stiffness coefficient: the stiffness of our grass blade, which will affect the force computations on our blade
Total gravity on the grass blade: environmental gravity + front gravity, which is the contribution of the gravity with respect to the front facing direction of the blade.
Recovery corresponds to the counter-force that brings our grass blade back into equilibrium. This is derived in the paper using Hooke's law.
Compare the current position of v2 to its original position before
simulation started, iv2, and compute the recovery forces as r = (iv2 - v2) * stiffness.
The wind function depends on the position of v0 and a function that changes with time, combined with cosine function, which will determine a wind direction that is affecting the blade, and the wind has a larger impact on grass blades whose forward directions are parallel to the wind direction.
Ingore blades that we won't need to render due to a variety of reasons.
When Front face direction of the grass blade is perpendicular to the view vector, as our grass blades won't have width, we will end up trying to render parts of the grass that are actually smaller than the size of a pixel, which could lead to aliasing artifacts. We can cull these blades.
We can also cull blades that are outside of the view-frustum,
Similarly to orientation culling, we can end up with grass blades that at large distances are smaller than the size of a pixel. This could lead to additional artifacts in our renders. We can cull grass blades as a function of their distance from the camera.
Here is a simple demonstration:
| NUM_BLADES | None | Orientation | View-frustum | Distance | All |
|---|---|---|---|---|---|
| 1 << 16 | 4.8 | 3.8 | 4.0 | 4.1 | 2.7 |
| 1 << 17 | 8.7 | 6.7 | 7.2 | 7.5 | 4.5 |
| 1 << 18 | 16.9 | 12.5 | 13.5 | 13.8 | 8.3 |
| 1 << 19 | 31.2 | 22.0 | 25.0 | 25.6 | 14.9 |
Test window size: Width: 1129; Height: 701;
Though the result shows that among 3 different methods, orientation one is better than view-frustum one, view-frustum one is better than distance one, the efficiency of these culling methods strongly depends on the camera. For example, if the camera is close enough, then lots of grass will be outside the view-frustum. However, if the camera is too far, then all the grass will be inside the view-frustum, so it won't be as good as other methods under such circumstance.



