Skip to content

Commit

Permalink
Readme
Browse files Browse the repository at this point in the history
  • Loading branch information
YueZhang1027 committed Oct 29, 2023
1 parent 7f57ea4 commit 9efb912
Show file tree
Hide file tree
Showing 27 changed files with 69 additions and 6 deletions.
53 changes: 52 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,66 @@ Here are the features implemented:
* Vulkan setups: add descriptor set layout for the compute shader and the grass vertex shader, update the descriptor sets and record command buffers. Bascially learning the complicated APIs.

### Tessellation level based on distance
The tesselation level is interpolated along `minTessLevel` and `maxTessLevel` based on the distance between camera and current `gl_position`. We draw the blades in `Quad` execution mode and we would like to add more tessellation along direction of height of blade, we assign calculated tessellation level to gl_TessLevelInner[1], gl_TessLevelOuter[0] and gl_TessLevelOuter[2] from the reference of this image(Domain parameterization for tessellation primitive modes).

![](img/quad.png)

Here is the chart for FPS (base camera position) comparision upon different settings:

||<div style="width:150px">Based on distance</div>|<div style="width:150px">TessLevel = 3</div>|<div style="width:150px">TessLevel = 5</div>|<div style="width:150px">TessLevel = 9</div>|
|----|----|----|----|----|
|Image|![](img/tessLevel/basedondist.png)|![](img/tessLevel/3.png)|![](img/tessLevel/5.png)|![](img/tessLevel/9.png)|
|FPS|658|759|699|580|

Tesslevel changed based on distance keep a visually pleasant outlook while improve the frame rate other than the fixed level method.

### Force Simulation
|<div style="width:150px">Gravity</div>|<div style="width:150px">Recovery+Gravity</div>|<div style="width:150px">Wind</div>|<div style="width:150px">Overall</div>|
|----|----|----|----|
|![](img/force/gravity.gif)|![](img/force/gravity_recover.gif)|![](img/force/wind.gif)|![](img/force/all.gif)|

Here are the GIFs for seperate force take place upon v2 in compute shader.

### Culling tests
#### Orientation test
|No test|threshold = 0.6|threshold = 0.7|threshold = 0.8|
|----|----|----|----|
|![](img/orientation/no.png)|![](img/orientation/0.6.png)|![](img/orientation/0.7.png)|![](img/orientation/0.8.png)|

I conducted orientation test based on the abs dot product between view direction and vector along the width of the blade. The higher threshold will cull more blades in the scene due to a stricter condition.

#### View frustum test
|No test|tolerance = 0.05|tolerance = 0.5|
|----|----|----|
|![](img/view_frustum/no.png)|![](img/view_frustum/0.05.png)|![](img/view_frustum/0.5.png)|

The view frustum test remove all blades doesn't enter the view frustum away to reduce computation. Higher tolerance will has a closer result to the result without this test, by keeping more grass by the edge.

#### Distance test

Here's the comparison for no test versus test with different paramters:

No distance test:
![](img/distance/no.png)

||dmax = 4|dmax = 16|
|----|----|----|
|n = 4|![](img/distance/4_4.png)|![](img/distance/4_16.png)|
|n = 16|![](img/distance/16_4.png)|![](img/distance/16_16.png)|

Larger n and larger distance threshold will all increase the culled blades count.

## Performance Analysis
### Different numbers of grass blades
For all the performance test, I enabled `VK_LAYER_LUNARG_monitor` layer to display FPS on the application window title. The setting can be changed in `instance.cpp`.

### Different number of grass blades
Here is a chart of frame rate versus number of grass blades:
![](img/num_of_blade.png)

As we may suppose, the higher blade related to a lower FPS. When the blades is of reasonable count(less than 1<<16 here), the decrease of FPS is proportional to the log of #blades. Otherwise, the performance decreases in a great scale and produce a bad visual output for user.

### Improvement from culling
Here is a chart of frame rate versus different culling methods in 1<<16 blade case:
![](img/cull_test.png)

Since the effect of culling largely rely on the paramters in culling method and the camera's view direction and position, the FPS may change largely for each methods. We may conclude from this chart that the three culling methods are effective in controlling the frame rate. Especially, the orientation test and view frustum test will optmize the scene largely without hurting the visual performance for grass-dense scene.
Binary file modified bin/Release/vulkan_grass_rendering.exe
Binary file not shown.
Binary file added img/cull_test.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/distance/16_16.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/distance/16_4.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/distance/4_16.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/distance/4_4.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/distance/no.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/force/all.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/force/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/force/gravity_recover.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/force/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/num_of_blade.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/orientation/0.6.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/orientation/0.7.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/orientation/0.8.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/orientation/no.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/quad.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/tessLevel/3.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/tessLevel/5.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/tessLevel/9.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/tessLevel/basedondist.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/view_frustum/0.05.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/view_frustum/0.5.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/view_frustum/no.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 6 additions & 4 deletions src/Instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
#include <vector>
#include "Instance.h"

#ifdef NDEBUG
const bool ENABLE_VALIDATION = false;
#else
const bool ENABLE_VALIDATION = true;
#endif

#define FPSTEST 1

namespace {
const std::vector<const char*> validationLayers = {
"VK_LAYER_KHRONOS_validation"
#if FPSTEST
, "VK_LAYER_LUNARG_monitor"
#endif // FPSTEST

};

// Get the required list of extensions based on whether validation layers are enabled
Expand Down
12 changes: 11 additions & 1 deletion src/shaders/compute.comp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#define WORKGROUP_SIZE 32

// test variables
#define orientation_test 1
#define view_frustum_test 1
#define distance_test 1

#define orientation_test_threshold 0.6
#define view_frustum_test_tolerance 0.7
#define distance_test_n 32
Expand Down Expand Up @@ -124,31 +128,37 @@ void main() {
blade.v2 = vec4(v2, width);
blades[gl_GlobalInvocationID.x] = blade;

// TODO: Cull blades that are too far away or not in the camera frustum and write them
// Cull blades that are too far away or not in the camera frustum and write them
// to the culled blades buffer
// Note: to do this, you will need to use an atomic operation to read and update numBlades.vertexCount
// You want to write the visible blades to the buffer without write conflicts between threads

#if orientation_test
// Orientation test
vec3 dirb = t1; // vector along the width of the blade
vec3 dirc = vec3(normalize(camera.view * vec4(0, 0, 1, 0)));// view direction
if (abs(dot(dirc, dirb)) < orientation_test_threshold) {
return;
}
#endif

#if view_frustum_test
// View-frustum test
mat4 VP = camera.proj * camera.view;
vec3 midpoint = 0.25f * v0 + 0.5f * v1 + 0.25f * v2;
if (!inViewFrustum(VP, v0) || !inViewFrustum(VP, midpoint) || !inViewFrustum(VP, v2)) {
return;
}
#endif

#if distance_test
// Distance test
vec3 c = vec3(inverse(camera.view) * vec4(0, 0, 0, 1)); // position of camera
float dproj = length(v0 - c - up * (v0 - c) * up);
if ((gl_GlobalInvocationID.x % distance_test_n) < floor(distance_test_n * (1.0f - dproj / distance_test_dmax))) {
return;
}
#endif

// Occlusion test
// TODO: Implement this test
Expand Down

0 comments on commit 9efb912

Please sign in to comment.