Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
81 changes: 76 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,81 @@ 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)
* Annie Qiu
* [LinkedIn](https://github.com/AnnieQiuuu/Project0-Getting-Started/blob/main/www.linkedin.com/in/annie-qiu-30531921a)
* Tested on: Windows 11, i9-12900H @2500 Mhz, 16GB, RTX 3070 Ti 8GB (Personal)

## Overview
This project is an implementation of 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). In this project, I use Vulkan to implement a grass simulator and renderer.The compute shaders are used to perform physics calculations on Bezier curves that represent individual grass blades in your application. Since rendering every grass blade on every frame will is fairly inefficient, you will 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 you will write several shaders.

### Features
- Simulating Forces
- Binding Resources
- Gravity
- Recovery
- Wind
- Culling tests
- Orientation culling
- View-frustum culling
- Distance culling
- Tessellating Bezier curves into grass blades
- Tessellate to varying levels of detail

## Screenshot

### Final demo
![](./img/demo.gif)

### Simulating Forces
This section explains how forces are simulated on grass blades that represented as Bezier curves within a compute shader.

#### Gracity only

![](./img/gravity.gif)

#### Recovery only
![](./img/recovery.gif)

#### Wind only
![](./img/wind.gif)

### Culling tests
To improve the efficiency, I cull the blades that may not require rendering. You can set `#define FrustumCulling 1`, `#define DistanceCulling 1` and `#define OrientationCulling 1` to 1 or 0 to check different culling techniques in compute.comp.

#### Orientation culling
![](./img/orient.gif)

#### View-frustum culling
![](./img/frusturm.gif)

#### Distance culling
![](./img/distance.gif)

## Performance Analysis

### Culling chart
![](./img/Culling.png)
The chart shows the performance of a grass rendering system measured in frames per second (FPS) as the number of grass blades decreased. The lower the FPS is, the better the performace.The chart compares different culling strategies:
- blue block: Original (no culling)
- red block: Frustum Culling
- yellow block: Distance Culling
- freeb block: Orientation Culling
- All Culling (combination of all three)
- X aixs: the number of blades from 2^18 to 2^8
- Y aixs: FPS
As the number of blades increases, the FPS goes down in all the situations. Frustum Culling improves the performance a lot, particularly noticeable with higher blade counts, as a large amount of blades outside the view are ignored. Distance culling improves a lot when the distance get further, as blades further than some certains of the threshold are ignored. Orientation culling imporves moderately by ignoring blades oriented away from viewer. The All culling (combination of all three strategies) improves the performance most. It demonstrates the compounded benefits of combingnni culling techniques.

### Dyamic Tessellation Level
![](./img/Tessel.png)
The chart shows the impact of dynamic tessellation levels on rendering performance measured in frames per second (FPS) as the number of grass blades decreased. It compares dynamic On and dynamic Off scenarios:
- X aixs: the number of blades from 2^18 to 2^8
- Y aixs: FPS
Enabling dynamic tessellation level of details significantly improves FPS, especially with higher numbers of grass blades. Tessellation reduces detail for distant grass blades, optimizing rendering performance.

## Resources
[helloTessellation sample](https://github.com/CIS565-Fall-2017/Vulkan-Samples/tree/master/samples/5_helloTessellation)
[tutorial on tessellation](https://ogldev.org/www/tutorial30/tutorial30.html)



### (TODO: Your README)

*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.
Binary file modified bin/Release/vulkan_grass_rendering.exe
Binary file not shown.
Binary file added img/Culling.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/Tessel.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/demo.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/frusturm.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/gravity.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/orient.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/recovery.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.
3 changes: 2 additions & 1 deletion src/Blades.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Blades::Blades(Device* device, VkCommandPool commandPool, float planeDim) : Mode

// Up vector and stiffness coefficient (up)
float stiffness = MIN_BEND + (generateRandomFloat() * (MAX_BEND - MIN_BEND));
//printf("stiffness: %f\n", stiffness);
currentBlade.up = glm::vec4(bladeUp, stiffness);

blades.push_back(currentBlade);
Expand All @@ -45,7 +46,7 @@ Blades::Blades(Device* device, VkCommandPool commandPool, float planeDim) : Mode
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::CreateBuffer(device, NUM_BLADES * sizeof(Blade), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, culledBladesBuffer, culledBladesBufferMemory);// add vertex buffer bit
BufferUtils::CreateBufferFromData(device, commandPool, &indirectDraw, sizeof(BladeDrawIndirect), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, numBladesBuffer, numBladesBufferMemory);
}

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 << 16;
constexpr static float MIN_HEIGHT = 1.3f;
constexpr static float MAX_HEIGHT = 2.5f;
constexpr static float MIN_WIDTH = 0.1f;
Expand Down
1 change: 1 addition & 0 deletions src/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Camera::Camera(Device* device, float aspectRatio) : device(device) {
r = 10.0f;
theta = 0.0f;
phi = 0.0f;
// position; look at; up
cameraBufferObject.viewMatrix = glm::lookAt(glm::vec3(0.0f, 1.0f, 10.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
cameraBufferObject.projectionMatrix = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f);
cameraBufferObject.projectionMatrix[1][1] *= -1; // y-coordinate is flipped
Expand Down
Loading