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
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.31)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")

project(cis565_project5_vulkan_grass_rendering)
Expand Down Expand Up @@ -63,4 +63,4 @@ ENDIF(WIN32)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/")

add_subdirectory(external)
add_subdirectory(src)
add_subdirectory(src)
80 changes: 75 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,80 @@ 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)
* Caroline Fernandes
* [LinkedIn](https://www.linkedin.com/in/caroline-fernandes-0-/), [personal website](https://0cfernandes00.wixsite.com/visualfx)
* Tested on: Windows 11, i9-14900HX @ 2.20GHz, Nvidia GeForce RTX 4070

### (TODO: Your README)
### Overview

*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.
The goal of this project was to get comfortable with Vulkan and implement [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). I am responsible for implementing the grass vertex, grass tessellation control/evaluate, grass fragment, and compute shaders.

In order to build the project, I made updates to CMakeLists.txt and updated the glfw folder to pull in the most recent from this repository https://github.com/glfw/glfw

<img src="img/final_output.gif" width="450">

## Grass Rendering
Each blade was represented by a bezier curve and three control points. De Castelajau's algorithm was used to construct the curve, and generate the triangle representation.

<img width="390" height="300" alt="image" src="https://github.com/user-attachments/assets/6f92d856-b80e-48d8-bc11-42d679e943c6" />

<img src="img/grass_rendering.gif" width="450">

**Note:** Values have been adjusted for the remaining videos to show off the effect

## Simulating Forces
These forces were summed and applied in the compute shader of the pipeline.

### Gravity
Gravity is implemented as the summation of environmental and "front" facing gravity (which is applied to the front viewing vector of the blade).

<img width="209" height="72" alt="image" src="https://github.com/user-attachments/assets/81debb17-2adf-4146-a9b5-b5484407c6c0" />

<img src="img/gravity.gif" width="450">

### Recovery

Recovery acts as a targeting force to bring the blade back to its starting position. The paper includes collisions, but my implementation was just influenced by the v2's current position, starting position, and a stiffness coefficient.

<img width="336" height="55" alt="image" src="https://github.com/user-attachments/assets/b104b6e4-b528-4110-bbad-4f80c6d13ede" />


### Wind

I simulated wind to be the combination of a wind direction and wind alignment. Blades with a forward vector aligned with the wind direction received more of an impact from the wind. Sin and Cosine waves that change over time were used to produce the waves.

<img width="338" height="281" alt="image" src="https://github.com/user-attachments/assets/23c0f349-bac3-4883-9784-a394f1eb6388" />

<img src="img/wind.gif" width="450">

## Culling

### Orientation Culling
Culls the blades with a front vector pointing away from the camera's look vector, because the width will become zero and rendering these pixels will produce rendering artifacts.

<img src="img/orientation_culling.gif" width="450">

### View Frustum Culling
Culls the blades that fall outside of the viewing frustum as they will not be visible.

<img src="img/viewFrustrum_culling.gif" width="450">

### Distance Culling
Culls the blades that are outside a defined range from the camera.

<img src="img/grass_dist_occl.gif" width="450">

## Performance Analysis
I tested using values suggested by the paper, however, the performance results did not match my expectations. Further turning of the parameters could reveal more obvious trends.

Culling Impact

<img src="img/numblades.png" width="450">

I tested different scene sizes with all three culling effects applied and compared that without those optimizations. This result was perhaps the most confusing, I had assumed the benefits of culling would outweigh the costs. In smaller scenes especially the opposite was true. In larger scenes the two results were comparable.

Culling Technique Breakdown

<img src="img/cullmethod.png" width="600">

Culling by blade orientation seemed to have the largest impact with smaller scenes, whereas with larger scenes the viewing frustum optimization seemed to be the most impactful.
1 change: 0 additions & 1 deletion external/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "Build the GLFW example programs")
set(GLFW_BUILD_TESTS OFF CACHE BOOL "Build the GLFW test programs")
set(GLFW_BUILD_DOCS OFF CACHE BOOL "Build the GLFW documentation")
Expand Down
61 changes: 61 additions & 0 deletions external/GLFW/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# EditorConfig for GLFW and its internal dependencies
#
# All files created by GLFW should indent with four spaces unless their format requires
# otherwise. A few files still use other indent styles for historical reasons.
#
# Dependencies have (what seemed to be) their existing styles described. Those with
# existing trailing whitespace have it preserved to avoid cluttering future commits.

root = true

[*]
charset = utf-8
end_of_line = lf

[include/GLFW/*.h]
indent_style = space
indent_size = 4

[{src,examples,tests}/*.{c,m,h,rc,in}]
indent_style = space
indent_size = 4

[CMakeLists.txt]
indent_style = space
indent_size = 4

[CMake/**.{cmake,in}]
indent_style = space
indent_size = 4

[*.{md}]
indent_style = space
indent_size = 4
trim_trailing_whitespace = false

[DoxygenLayout.xml]
indent_style = space
indent_size = 2

[docs/*.{scss,html}]
indent_style = tab
indent_size = unset

[deps/getopt.{c,h}]
indent_style = space
indent_size = 2

[deps/linmath.h]
indent_style = tab
tab_width = 4
indent_size = 4
trim_trailing_whitespace = false

[deps/nuklear*.h]
indent_style = space
indent_size = 4

[deps/tinycthread.{c,h}]
indent_style = space
indent_size = 2

8 changes: 8 additions & 0 deletions external/GLFW/.github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

* @elmindreda

docs/*.css @glfw/webdev
docs/*.scss @glfw/webdev
docs/*.html @glfw/webdev
docs/*.xml @glfw/webdev

100 changes: 100 additions & 0 deletions external/GLFW/.github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Build
on:
pull_request:
push:
branches: [ ci, master, latest, 3.3-stable ]
workflow_dispatch:
permissions:
statuses: write
contents: read

jobs:
build-linux-clang:
name: Linux (Clang)
runs-on: ubuntu-latest
timeout-minutes: 4
env:
CC: clang
CFLAGS: -Werror
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt update
sudo apt install libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev libwayland-dev libxkbcommon-dev

- name: Configure Null shared library
run: cmake -B build-null-shared -D GLFW_BUILD_WAYLAND=OFF -D GLFW_BUILD_X11=OFF -D BUILD_SHARED_LIBS=ON
- name: Build Null shared library
run: cmake --build build-null-shared --parallel

- name: Configure X11 shared library
run: cmake -B build-x11-shared -D GLFW_BUILD_WAYLAND=OFF -D GLFW_BUILD_X11=ON -D BUILD_SHARED_LIBS=ON
- name: Build X11 shared library
run: cmake --build build-x11-shared --parallel

- name: Configure Wayland shared library
run: cmake -B build-wayland-shared -D GLFW_BUILD_WAYLAND=ON -D GLFW_BUILD_X11=OFF -D BUILD_SHARED_LIBS=ON
- name: Build Wayland shared library
run: cmake --build build-wayland-shared --parallel

- name: Configure Wayland+X11 static library
run: cmake -B build-full-static -D GLFW_BUILD_WAYLAND=ON -D GLFW_BUILD_X11=ON
- name: Build Wayland+X11 static library
run: cmake --build build-full-static --parallel

- name: Configure Wayland+X11 shared library
run: cmake -B build-full-shared -D GLFW_BUILD_WAYLAND=ON -D BUILD_SHARED_LIBS=ON -D GLFW_BUILD_X11=ON
- name: Build Wayland+X11 shared library
run: cmake --build build-full-shared --parallel

build-macos-clang:
name: macOS (Clang)
runs-on: macos-latest
timeout-minutes: 4
env:
CFLAGS: -Werror
MACOSX_DEPLOYMENT_TARGET: 10.11
CMAKE_OSX_ARCHITECTURES: x86_64;arm64
steps:
- uses: actions/checkout@v4

- name: Configure Null shared library
run: cmake -B build-null-shared -D GLFW_BUILD_COCOA=OFF -D BUILD_SHARED_LIBS=ON
- name: Build Null shared library
run: cmake --build build-null-shared --parallel

- name: Configure Cocoa static library
run: cmake -B build-cocoa-static
- name: Build Cocoa static library
run: cmake --build build-cocoa-static --parallel

- name: Configure Cocoa shared library
run: cmake -B build-cocoa-shared -D BUILD_SHARED_LIBS=ON
- name: Build Cocoa shared library
run: cmake --build build-cocoa-shared --parallel

build-windows-vs2022:
name: Windows (VS2022)
runs-on: windows-latest
timeout-minutes: 4
env:
CFLAGS: /WX
steps:
- uses: actions/checkout@v4

- name: Configure Win32 shared x86 library
run: cmake -B build-win32-shared-x86 -G "Visual Studio 17 2022" -A Win32 -D BUILD_SHARED_LIBS=ON
- name: Build Win32 shared x86 library
run: cmake --build build-win32-shared-x86 --parallel

- name: Configure Win32 static x64 library
run: cmake -B build-win32-static-x64 -G "Visual Studio 17 2022" -A x64
- name: Build Win32 static x64 library
run: cmake --build build-win32-static-x64 --parallel

- name: Configure Win32 shared x64 library
run: cmake -B build-win32-shared-x64 -G "Visual Studio 17 2022" -A x64 -D BUILD_SHARED_LIBS=ON
- name: Build Win32 shared x64 library
run: cmake --build build-win32-shared-x64 --parallel

10 changes: 10 additions & 0 deletions external/GLFW/.mailmap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Camilla Löwy <elmindreda@glfw.org> <elmindreda@users.sourceforge.net>
Camilla Löwy <elmindreda@glfw.org> <elmindreda@elmindreda.org>
Camilla Löwy <elmindreda@glfw.org>

Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>

Marcus Geelnard <m@bitsnbites.eu> <marcus256@users.sourceforge.net>
Marcus Geelnard <m@bitsnbites.eu> <marcus@geelnards-pc.(none)>
Marcus Geelnard <m@bitsnbites.eu>

23 changes: 20 additions & 3 deletions external/GLFW/CMake/GenerateMappings.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Usage:
# cmake -P GenerateMappings.cmake <path/to/mappings.h.in> <path/to/mappings.h>

cmake_policy(VERSION 3.16)

set(source_url "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt")
set(source_path "${CMAKE_CURRENT_BINARY_DIR}/gamecontrollerdb.txt")
set(template_path "${CMAKE_ARGV3}")
Expand All @@ -22,9 +24,24 @@ if (status_code)
endif()

file(STRINGS "${source_path}" lines)
foreach(line ${lines})
if ("${line}" MATCHES "^[0-9a-fA-F].*$")
set(GLFW_GAMEPAD_MAPPINGS "${GLFW_GAMEPAD_MAPPINGS}\"${line}\\n\"\n")
list(FILTER lines INCLUDE REGEX "^[0-9a-fA-F]")

foreach(line IN LISTS lines)
if (line MATCHES "platform:Windows")
if (GLFW_WIN32_MAPPINGS)
string(APPEND GLFW_WIN32_MAPPINGS "\n")
endif()
string(APPEND GLFW_WIN32_MAPPINGS "\"${line}\",")
elseif (line MATCHES "platform:Mac OS X")
if (GLFW_COCOA_MAPPINGS)
string(APPEND GLFW_COCOA_MAPPINGS "\n")
endif()
string(APPEND GLFW_COCOA_MAPPINGS "\"${line}\",")
elseif (line MATCHES "platform:Linux")
if (GLFW_LINUX_MAPPINGS)
string(APPEND GLFW_LINUX_MAPPINGS "\n")
endif()
string(APPEND GLFW_LINUX_MAPPINGS "\"${line}\",")
endif()
endforeach()

Expand Down
38 changes: 38 additions & 0 deletions external/GLFW/CMake/Info.plist.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSRequiresCarbon</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
29 changes: 29 additions & 0 deletions external/GLFW/CMake/cmake_uninstall.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

if (NOT EXISTS "@GLFW_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: \"@GLFW_BINARY_DIR@/install_manifest.txt\"")
endif()

file(READ "@GLFW_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")

foreach (file ${files})
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if (EXISTS "$ENV{DESTDIR}${file}")
exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval)
if (NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
endif()
elseif (IS_SYMLINK "$ENV{DESTDIR}${file}")
EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval)
if (NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing symlink \"$ENV{DESTDIR}${file}\"")
endif()
else()
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif()
endforeach()

Loading