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
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,29 @@ The following resources may be useful for this project.
## README

* A brief description of the project and the specific features you implemented.
* In this project, I implemented the grass representation using tessellation based on next-gen graphics API Vulkan. The tessellation level is based on the distance from the camera to the grass blade.
* Besides the basic grass shading, I also let natural force applying on the grass following 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)". There are three natural forces I added here: gravity, recovery and wind force.
* Furthermore, in order to optimize the performance of grass rendering. I added three culling methods on the scene: orientation culling, view-frustum culling and distance culling.
* orientation culling is based on angle between the direction of the width of the blade and the camera orientation. If they align too much, the blade might not be able to fill the whole pixel, causing rendering problems
* view-frustum culling is based on the idea that if we can't see it, we don't need to draw it. Hence, we check whether the v0(origin of blade), v2(blade tip) and m(mass center of blade) are inside the view-frustum. If not, we cull it out.
* distance culling is based on the idea that if the distance is too far away, we can't see that many blades in the same area very detailed far away from the camera. So cull some of the baldes to improve the performance.
* GIFs of your project in its different stages with the different features being added incrementally.
* A performance analysis (described below).
* without any force and culling
* ![](img/grass_without_force.PNG)
* With gravity
* ![](img/grass_with_gravity.PNG)
* With wind force and recovery force
* ![](img/grass_with_wind.gif)
* With view-frustum culling and orientation culling (notice the boundary of window)
* ![](img/frustum_culling.gif)
* With distance culling
* ![](img/distance_cull.gif)
* A performance analysis.
* Time R.S.T then number of blades
* ![](img/blade_num_chart.png)
* culling efficiency
* ![](img/culling_method_efficiency.png)
* From the chart above we can easily see the performance improvement by applying the culling methods. Among them, the distance culling improve the performance most. The frustum culling has a better result when the camera is looking at the corner of the ground.

### Performance Analysis

Expand All @@ -300,3 +321,16 @@ The template of the comment section of your pull request is attached below, you
* Feature 1
* ...
* Feedback on the project itself, if any.



### Acknowledgements

- [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)
- [Vulkan Tutorial](https://vulkan-tutorial.com/)
- [Project 4 Recitation Slides](https://docs.google.com/presentation/d/1WqIPLlli2l5A2QfgPOl1cqqkvSRPjiid9OYzSlkAWxM/edit#slide=id.g25e0d401a4_0_90)
- [Introduction to Vulkan](https://docs.google.com/presentation/d/1zTqdnUV5hGuff6mPutvc9ZOzHJAPbdm4OzkYXTIZTSE/edit#slide=id.p)
- [Tessellation Tutorial](http://in2gpu.com/2014/07/12/tessellation-tutorial-opengl-4-3/)
- Hannah and Josh for helped me build up the compute pipeline
- Yan Dong helped me a lot when I implemented the grass fragment shader as well as debug the compute pipeline and compute shader
- Jie Meng helped me figure out the dynamic tessellation level based on distance to camera
Binary file added img/blade_num_chart.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/culling_method_efficiency.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/debug_dist.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/debug_dist_2.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_cull.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/frustum_culling.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_with_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/grass_with_wind.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_without_force.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/tes_error.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/validation_layer_error_vertex_buffer_bind.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/Blades.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Blades::Blades(Device* device, VkCommandPool commandPool, float planeDim) : Mode
currentBlade.v1 = glm::vec4(bladePosition + bladeUp * height, height);

// Physical model guide and width (v2)
// v2 is the same as v1 at the beginning
float width = MIN_WIDTH + (generateRandomFloat() * (MAX_WIDTH - MIN_WIDTH));
currentBlade.v2 = glm::vec4(bladePosition + bladeUp * height, width);

Expand All @@ -44,9 +45,10 @@ 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);
//need to modify to eliminate the error shown in console
BufferUtils::CreateBufferFromData(device, commandPool, blades.data(), NUM_BLADES * sizeof(Blade), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_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, &indirectDraw, sizeof(BladeDrawIndirect), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, numBladesBuffer, numBladesBufferMemory);
}

VkBuffer Blades::GetBladesBuffer() const {
Expand Down
12 changes: 6 additions & 6 deletions src/Blades.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
#include <array>
#include "Model.h"

constexpr static unsigned int NUM_BLADES = 1 << 13;
constexpr static float MIN_HEIGHT = 1.3f;
constexpr static float MAX_HEIGHT = 2.5f;
constexpr static unsigned int NUM_BLADES = 1 << 20;
constexpr static float MIN_HEIGHT = 0.8f;
constexpr static float MAX_HEIGHT = 1.5f;
constexpr static float MIN_WIDTH = 0.1f;
constexpr static float MAX_WIDTH = 0.14f;
constexpr static float MIN_BEND = 7.0f;
constexpr static float MAX_BEND = 13.0f;
constexpr static float MAX_WIDTH = 0.18f;
constexpr static float MIN_BEND = 15.0f;
constexpr static float MAX_BEND = 20.0f;

struct Blade {
// Position and direction
Expand Down
Loading