Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project 5: DI LU #6

Open
wants to merge 53 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
57ce7be
Add blades of grass.
dluisnothere Oct 30, 2022
6613feb
some culling work done.
dluisnothere Oct 30, 2022
c282bf1
Complete culling.
dluisnothere Oct 30, 2022
92eebdd
Add image
dluisnothere Oct 30, 2022
28d1645
Update README.md
dluisnothere Oct 30, 2022
55518a1
Update README.md
dluisnothere Oct 30, 2022
0e33e0f
Update README.md
dluisnothere Oct 30, 2022
37275ff
add image
dluisnothere Oct 30, 2022
3aafd34
Update README.md
dluisnothere Oct 30, 2022
b840f50
Update README.md
dluisnothere Oct 30, 2022
1b30134
Update README.md
dluisnothere Oct 30, 2022
180847b
Update README.md
dluisnothere Oct 30, 2022
e79e6e7
add image
dluisnothere Oct 30, 2022
9ad429d
Update README.md
dluisnothere Oct 30, 2022
d876983
Update README.md
dluisnothere Oct 30, 2022
8a37349
Update README.md
dluisnothere Oct 30, 2022
1f4d0eb
Update README.md
dluisnothere Oct 30, 2022
3a77d2e
Update README.md
dluisnothere Oct 30, 2022
6b70977
Update README.md
dluisnothere Oct 30, 2022
67ee063
Update README.md
dluisnothere Oct 30, 2022
ac33a0e
Update README.md
dluisnothere Oct 30, 2022
272f7e8
Update README.md
dluisnothere Oct 30, 2022
d5c0169
Update README.md
dluisnothere Oct 30, 2022
58c6d8b
Update README.md
dluisnothere Oct 30, 2022
cf78027
Update README.md
dluisnothere Oct 30, 2022
26bb4ea
Update README.md
dluisnothere Oct 30, 2022
1dc9291
Update README.md
dluisnothere Oct 30, 2022
056a54e
Update README.md
dluisnothere Oct 30, 2022
66547b9
Update README.md
dluisnothere Oct 30, 2022
7ba7130
Update README.md
dluisnothere Oct 30, 2022
45bd8ab
Update README.md
dluisnothere Oct 30, 2022
4456e7e
Update README.md
dluisnothere Oct 30, 2022
221db25
Update README.md
dluisnothere Oct 30, 2022
19c8558
Update README.md
dluisnothere Oct 30, 2022
1437660
Update README.md
dluisnothere Oct 30, 2022
1921939
Update README.md
dluisnothere Oct 30, 2022
0f8acb1
Update README.md
dluisnothere Oct 30, 2022
408f3ad
add images
dluisnothere Oct 30, 2022
65e0622
Update README.md
dluisnothere Oct 30, 2022
3637c30
add gif
dluisnothere Oct 30, 2022
546f0b8
Update README.md
dluisnothere Oct 30, 2022
3fe74a8
Update README.md
dluisnothere Oct 30, 2022
e88dcd6
Update README.md
dluisnothere Oct 30, 2022
e08021a
Update README.md
dluisnothere Oct 30, 2022
407e72a
Update README.md
dluisnothere Oct 30, 2022
5ff926f
add gifs
dluisnothere Oct 31, 2022
e625a14
Update README.md
dluisnothere Oct 31, 2022
9598ecd
Update README.md
dluisnothere Oct 31, 2022
d32ab9d
Update README.md
dluisnothere Oct 31, 2022
8a129c5
Update README.md
dluisnothere Oct 31, 2022
736e2b8
Add images
dluisnothere Oct 31, 2022
5ef3401
Update README.md
dluisnothere Oct 31, 2022
61bc2bb
Update README.md
dluisnothere Oct 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 107 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,112 @@ Vulkan Grass Rendering

**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 5**

* (TODO) YOUR NAME HERE
* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab)
* Di Lu
* [LinkedIn](https://www.linkedin.com/in/di-lu-0503251a2/)
* [personal website](https://www.dluisnothere.com/)
* Tested on: Windows 11, i7-12700H @ 2.30GHz 32GB, NVIDIA GeForce RTX 3050 Ti

### (TODO: Your README)
## Introduction

*DO NOT* leave the README to the last minute! It is a crucial part of the
project, and we will not be able to grade you without a good README.
This is my first Vulkan project, which simulates grass movement in an outdoor environment based on the paper: [Responsive Real-Time Grass Rendering for General 3D Scenes](https://www.cg.tuwien.ac.at/research/publications/2017/JAHRMANN-2017-RRTG/JAHRMANN-2017-RRTG-draft.pdf)

This simulation is broken into three parts: Tessellation of the grass blade into some particular shape (in my case, a quadric knife shape), physics calcuations in a compute shader for grass movements, and culling unnecessary blades for performance. For the physics element of the simulation, the following three environmental forces are considered:
- Recovery: A force based on stiffness of a blade that counteracts external forces of gravity and wind
- Gravity: Gravitational force from the ground
- Wind: Force applied by wind and air
- Result Validation (to clamp the recalculated blade shape's length and position)
- **Note that the paper also specifies Collision force, but we don't take that into account here**

![](img/diGrass2.gif)

## Core Features and Results

### 1. Grass Shape Tessellation

At the initial stage of the project, there is only a patch of dirt with no visible grass on it. This is because all grass blades initially are represented by one vertex. In order for grass blades to appear, we must tessellate the vertex into a surface curve that represents the grass blade's shape. Based on Real-Time Grass Rendering, grass can be suggested to follow these possible curves:

<img src="https://github.com/dluisnothere/Project5-Vulkan-Grass-Rendering/blob/main/img/bladeShape.png" width="600">

For my project, I chose #3, the quadric "blade" shape for my grass.

Furthermore, each grass blade is controlled by a series of control points illustrated by the following diagram:

![](img/blade_model.jpg)

- `v0`: fixed base point of a grass blade
- `v1`: this point is "interpolated"/calculated as a response to `v2` and `v0`
- `v2`: this point gets moved based on the environmental forces
- `up`: The blade's up vector which sprouts from the ground upward in the Y direction. This is the same as the normal of the pane.

Each of the above points are represented as `vec4s` where the element _w_ (fourth element) represents the following:

- `v0.w - theta`: angle of rotation of the grass blade. This is different for every blade of grass which will give variety to the grass patterns.
- `v1.w - blade height`: height of the grass blade
- `v2.w - blade width`: width of the base of the blade
- `up.w - blade stiffness`: stiffness of the blade/resistance towards the environmental forces

Here is the simulation without any forces:

![](img/grass.png)

### 2. Environmental Forces

There are three environmental forces that impact the grass blade:

- Recovery: A force based on stiffness of a blade that counteracts external forces of gravity and wind
- Gravity: Gravitational force from the ground
- Wind: Force applied by wind and air

#### Gravity

With only gravity active, all grass blades will collapse to the ground. Gravitational force is a combination of `frontal gravity` and `downward gravity`. Environmental gravity acts along a vector of influence which is orthogonal to the width of the blade of the grass (along the face forward direction of the grass). Here is an image of the result with just gravity:

![](img/gravity.png)

#### Resistance

Resistance factor is calculated by taking into account a stiffness constant defined by each grass blade. We essentially render the blade between the fully upstanding position and the collapsed ground position.

![](img/resistance.png)

#### Wind

Wind factor is calculated by using a procedural sinusoidal wave and fbm noise to calculate some noise factor applied to the vector displacement.

![](img/wind.gif)

### 3. Culling

#### Rotational Culling

Rotational Culling removes blades such that its face-forward is exacty orthongal to the camera view vector towards the blade. This is because a blade has no thickness, so at that angle, there is no reason to send it to the render pipeline.

![](img/rotation.gif)

#### Frustum Culling

Frustum Culling removes blades that are outside of your viewport. With my implementation, there is a slight border where I remove blades within the frame as well so you can see the effect more clearly.

![](img/frustum.gif)

#### Distance Culling

Distance Culling removes blades that are outside of a certain distance.

![](img/distance.gif)

## Performance Analysis

**Performance Measurements vs. Number of Blades**

![](img/fpsNumBlades.png)

Based on the measurement of FPS above, increasing the number of blades will decrease FPS, as expected.

**Performance Measurements vs. Different Culling Methods over an increasing number of blades**

![](img/lastChart.png)

This chart above is a comparison of performance between NO culling, Frustum Culling, Orientation Culling, Distance Culling, and ALL culling. However, the results are a little bit difficult to generalize. This is because each of the three culling methods work best for different scenarios/setups. For example, Frustum culling works best when you are really zoomed in on a patch of few blades. Orientation culling can be more accurately understood by the graph above since all the grass blades are oriented randomly. Distance culling works best when you can compare the results between being far away from the scene vs. being close up. However, it's easy to see from above that having ALL culling turned on is generally better than having No Culling at all.

## Bloopers! :)
Binary file added bin/Debug/vulkan_grass_rendering.exe
Binary file not shown.
Binary file added bin/Debug/vulkan_grass_rendering.pdb
Binary file not shown.
Binary file modified bin/Release/vulkan_grass_rendering.exe
Binary file not shown.
Binary file added img/bladeShape.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/diGrass.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/diGrass2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/distance.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/fpsNumBlades.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/frustum.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/grass.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/gravity.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/lastChart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/resistance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/rotation.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/wind.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions src/Blades.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ Blades::Blades(Device* device, VkCommandPool commandPool, float planeDim) : Mode
indirectDraw.firstVertex = 0;
indirectDraw.firstInstance = 0;

BufferUtils::CreateBufferFromData(device, commandPool, blades.data(), NUM_BLADES * sizeof(Blade), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, bladesBuffer, bladesBufferMemory);
BufferUtils::CreateBuffer(device, NUM_BLADES * sizeof(Blade), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, culledBladesBuffer, culledBladesBufferMemory);
BufferUtils::CreateBufferFromData(device, commandPool, &indirectDraw, sizeof(BladeDrawIndirect), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, numBladesBuffer, numBladesBufferMemory);
BufferUtils::CreateBufferFromData(device, commandPool, blades.data(), NUM_BLADES * sizeof(Blade), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, bladesBuffer, bladesBufferMemory);
BufferUtils::CreateBuffer(device, NUM_BLADES * sizeof(Blade), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, culledBladesBuffer, culledBladesBufferMemory);
BufferUtils::CreateBufferFromData(device, commandPool, &indirectDraw, sizeof(BladeDrawIndirect), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, numBladesBuffer, numBladesBufferMemory);
}

VkBuffer Blades::GetBladesBuffer() const {
Expand Down
2 changes: 1 addition & 1 deletion src/Blades.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <array>
#include "Model.h"

constexpr static unsigned int NUM_BLADES = 1 << 13;
constexpr static unsigned int NUM_BLADES = 1 << 22;
constexpr static float MIN_HEIGHT = 1.3f;
constexpr static float MAX_HEIGHT = 2.5f;
constexpr static float MIN_WIDTH = 0.1f;
Expand Down
Loading