Skip to content

Commit

Permalink
misc/refactor: restructure project (#16)
Browse files Browse the repository at this point in the history
* Refactor project structure

* Update artifact path

* Fix wrong include path

* Fix shader path

* Update CI and README

* Rename workflow

* Update README.md
  • Loading branch information
shg8 authored Mar 14, 2024
1 parent 11bbd84 commit 473818d
Show file tree
Hide file tree
Showing 56 changed files with 19,805 additions and 19,733 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
name: CMake on multiple platforms
name: Windows, Linux, macOS

on:
push:
Expand Down Expand Up @@ -91,5 +91,5 @@ jobs:
with:
name: vulkan_splatting-${{ matrix.os }}-${{ matrix.c_compiler }}-${{ matrix.build_type }}
path: |
${{ steps.strings.outputs.build-output-dir }}/vulkan_splatting
${{ steps.strings.outputs.build-output-dir }}/Release/vulkan_splatting.exe
${{ steps.strings.outputs.build-output-dir }}/apps/viewer/vulkan_splatting_viewer
${{ steps.strings.outputs.build-output-dir }}/apps/viewer/vulkan_splatting_viewer.exe
136 changes: 16 additions & 120 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.26)
project(vulkan_splatting)
project(vulkan_splatting_root)

include(FetchContent)

Expand Down Expand Up @@ -43,7 +43,6 @@ else ()
find_package(glm REQUIRED)
endif ()


FetchContent_Declare(libenvpp
GIT_REPOSITORY https://github.com/ph3at/libenvpp.git
GIT_TAG v1.0.0
Expand All @@ -70,127 +69,24 @@ if (APPLE)
add_compile_definitions(__APPLE__)
endif ()

file(GLOB_RECURSE GLSL_SOURCE_FILES
"shaders/*.frag"
"shaders/*.vert"
"shaders/*.comp"
)

if (CMAKE_BUILD_TYPE MATCHES Debug)
add_compile_definitions(DEBUG)
else ()
add_compile_definitions(NDEBUG)
endif ()

if (CMAKE_BUILD_TYPE MATCHES Debug AND NOT APPLE)
list(APPEND GLSLC_DEFINE "-DDEBUG")
else ()
list(APPEND GLSLC_DEFINE "-DNDEBUG")
endif ()

if (APPLE)
# append -DAPPLE to GLSLC_DEFINE
list(APPEND GLSLC_DEFINE "-DAPPLE")
endif ()

add_executable(embedfile cmake/embedfile.c)

set(SHADER_HEADER "${PROJECT_BINARY_DIR}/shaders/shaders.h")
message(STATUS "Shader header file: ${SHADER_HEADER}")

# Delete old header file
add_custom_command(
OUTPUT ${SHADER_HEADER}
COMMAND ${CMAKE_COMMAND} -E remove ${SHADER_HEADER}
DEPENDS ${GLSL_SOURCE_FILES}
)

foreach (GLSL ${GLSL_SOURCE_FILES})
get_filename_component(FILE_NAME ${GLSL} NAME_WE)
string(TOUPPER ${FILE_NAME} FILE_NAME_UPPER)
set(FILE_NAME_UPPER "SPV_${FILE_NAME_UPPER}")
set(SPIRV "${PROJECT_BINARY_DIR}/shaders/${FILE_NAME}.spv")
SET(TEMP_HEADER "${PROJECT_BINARY_DIR}/shaders/${FILE_NAME}.h")
add_custom_command(
OUTPUT ${SPIRV}
COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/shaders/"
COMMAND ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE} "--target-env" "vulkan1.2" -V ${GLSL} -o ${SPIRV} ${GLSLC_DEFINE}
DEPENDS ${GLSL})
list(APPEND SPIRV_BINARY_FILES ${SPIRV})

add_custom_command(
OUTPUT ${SHADER_HEADER}
COMMAND embedfile ${FILE_NAME_UPPER} ${SPIRV} ${SHADER_HEADER}
DEPENDS ${SPIRV}
APPEND)

list(APPEND TEMP_HEADERS ${TEMP_HEADER})
endforeach (GLSL)

add_custom_target(
Shaders
DEPENDS ${SPIRV_BINARY_FILES} ${SHADER_HEADER}
)
include_directories(${PROJECT_BINARY_DIR}/shaders)

include_directories(third_party)

file(GLOB EXTERNAL_SOURCE
${imgui_SOURCE_DIR}/*.cpp
${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp
${imgui_SOURCE_DIR}/backends/imgui_impl_vulkan.cpp
third_party/implot/implot.cpp
third_party/implot/implot_demo.cpp
third_party/implot/implot_items.cpp
)

add_executable(vulkan_splatting main.cpp
vulkan/VulkanContext.cpp
3dgs/Renderer.cpp
vulkan/Window.cpp
3dgs/GSScene.cpp
vulkan/Shader.cpp
vulkan/Utils.cpp
vulkan/VMA.cpp
vulkan/Buffer.cpp
vulkan/Buffer.h
vulkan/pipelines/Pipeline.cpp
vulkan/pipelines/Pipeline.h
vulkan/DescriptorSet.cpp
vulkan/DescriptorSet.h
vulkan/pipelines/ComputePipeline.cpp
vulkan/pipelines/ComputePipeline.h
vulkan/Swapchain.cpp
vulkan/Swapchain.h
${EXTERNAL_SOURCE}
vulkan/ImguiManager.cpp
vulkan/ImguiManager.h
vulkan/QueryManager.cpp
vulkan/QueryManager.h
3dgs/GUIManager.cpp
3dgs/GUIManager.h
)

add_dependencies(vulkan_splatting Shaders)

target_include_directories(vulkan_splatting PUBLIC
${Vulkan_INCLUDE_DIRS}
${GLM_INCLUDE_DIRS}
${glm_SOURCE_DIR}
${imgui_SOURCE_DIR}
${imgui_SOURCE_DIR}/backends
${spdlog_SOURCE_DIR}/include
)

target_link_libraries(vulkan_splatting PUBLIC glfw libenvpp::libenvpp spdlog::spdlog)
target_link_libraries(vulkan_splatting PUBLIC Vulkan::Vulkan)
if (UNIX)
target_link_libraries(vulkan_splatting PUBLIC ${CMAKE_DL_LIBS})
endif ()

add_custom_command(TARGET vulkan_splatting POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:vulkan_splatting>/shaders/"
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_BINARY_DIR}/shaders"
"$<TARGET_FILE_DIR:vulkan_splatting>/shaders"
)
add_subdirectory(src)
add_subdirectory(apps)

#add_custom_target(
# Shaders
# DEPENDS ${SPIRV_BINARY_FILES} ${SHADER_HEADER}
#)
#include_directories(${PROJECT_BINARY_DIR}/shaders)

#add_custom_command(TARGET vulkan_splatting POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:vulkan_splatting>/shaders/"
# COMMAND ${CMAKE_COMMAND} -E copy_directory
# "${PROJECT_BINARY_DIR}/shaders"
# "$<TARGET_FILE_DIR:vulkan_splatting>/shaders"
#)
57 changes: 43 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
# VulkanSplatting
VulkanSplatting is an (not-yet-highly-) optimized, cross-platform implementation of [Gaussian Splatting](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/) using the [Vulkan API](https://www.khronos.org/vulkan/) and compute pipelines.

VulkanSplatting is an (not-yet-) highly optimized, cross-platform implementation
of [Gaussian Splatting](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/) using
the [Vulkan API](https://www.khronos.org/vulkan/) and compute pipelines.

Why Vulkan? We want to democratize the access to high-performance point-based radiance fields.
Existing implementations of Gaussian Splatting are often limited to CUDA, which only runs on NVIDIA GPUs,
and OpenGL is deprecated on Apple platforms. Additionally, Vulkan's compute capabilities are the closest to CUDA's
with support for warp-level primitives (subgroups).

[![Windows + Linux](https://github.com/shg8/VulkanSplatting/actions/workflows/cmake-multi-platform.yml/badge.svg?branch=main)](https://github.com/shg8/VulkanSplatting/actions/workflows/cmake-multi-platform.yml)

![VulkanSplatting Demo macOS](https://github.com/shg8/VulkanSplatting/assets/38004233/66542056-ce30-4998-a612-dd4f6792599e)

## Command Line Usage

```
./vulkan_splatting [options] <input_file.ply>
```
Expand All @@ -20,29 +29,42 @@ VulkanSplatting is an (not-yet-highly-) optimized, cross-platform implementation

- `-i`, `--immediate-swapchain`: Set swapchain mode to immediate (VK_PRESENT_MODE_IMMEDIATE_KHR)

- `-w`, `--width <width>`: Set window width

- `-h`, `--height <height>`: Set window height

- `--no-gui`: Disable GUI

## Building

### Linux

VulkanSplatting requires the following dependencies:

`Vulkan headers, Vulkan validation layers, glslangValidator, glfw, glm`

The easiest way to install the first three is through the [LunarG Vulkan SDK](https://www.lunarg.com/vulkan-sdk/). Alternatively, you can install the corresponding packages from your distro. For Ubuntu, the packages to install are `vulkan-headers, vulkan-validationlayers, glslang-dev, libglfw3-dev, libglm-dev`.
The easiest way to install the first three is through the [LunarG Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).
Alternatively, you can install the corresponding packages from your distro. For Ubuntu, the packages to install
are `vulkan-headers, vulkan-validationlayers, glslang-dev, libglfw3-dev, libglm-dev`.

### Windows
After installing Vulkan SDK, set the `VULKAN_SDK` environmental variable to the install path. Alternatively, pass `-DVULKAN_SDK=\INSTALL\LOCATION\OF\YOUR\SDK` to CMake when configuring.

After installing Vulkan SDK, set the `VULKAN_SDK` environmental variable to the install path. Alternatively,
pass `-DVULKAN_SDK=\INSTALL\LOCATION\OF\YOUR\SDK` to CMake when configuring.

A full CMake configure command is as follows:

```
mkdir .\VulkanSplatting\build
cmake -DCMAKE_BUILD_TYPE=Release -DVULKAN_SDK=\INSTALL\LOCATION\OF\YOUR\SDK -S .\VulkanSplatting -B .\VulkanSplatting\build
```

### macOS

After installing the Vulkan SDK, please proceed with CMake configuration and build steps as usual.

## TODO

- [x] Better controls and GUI on GLFW
- [ ] Implement SOTA parallel radix sort
- [ ] Use Vulkan subgroups to batch Gaussian retrievals at the warp level
Expand All @@ -53,17 +75,24 @@ After installing the Vulkan SDK, please proceed with CMake configuration and bui

Please feel free to open an issue if you have any feature suggestions or are interested in contributing.

## Contributing
If you are interested in integrating your Gaussian Splatting variant, please open an issue or a pull request.
VulkanSplatting's shaders follow the procedures outlined in the original paper, so it should be relatively
easy to port your CUDA code. With cross-platform support, it's a great way to expand the reach and adoption of your research.
If there are any questions, feel free to [send me an email](mailto:[email protected]).

## License
The project is licensed under LGPL. If that is not permissive enough for your project, please feel free to [send me an email](mailto:[email protected]).

The main project is licensed under LGPL.

This project uses several third-party libraries. Here is a list of these libraries along with their respective licenses:

- **GLM**: Licensed under the [MIT License](https://opensource.org/licenses/MIT).
- **args.hxx**: Licensed under the [MIT License](https://opensource.org/licenses/MIT).
- **spdlog**: Licensed under the [MIT License](https://opensource.org/licenses/MIT).
- **ImGUI**: Licensed under the [MIT License](https://opensource.org/licenses/MIT).
- **Vulkan Memory Allocator**: Licensed under the [MIT License](https://opensource.org/licenses/MIT).
- **VkRadixSort**: Licensed under the [MIT License](https://opensource.org/licenses/MIT).
- **implot**: Licensed under the [MIT License](https://opensource.org/licenses/MIT).
- **glfw**: Licensed under the [zlib/libpng license](https://www.glfw.org/license.html).
- **libenvpp**: Licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
- **GLM**: [MIT License](https://opensource.org/licenses/MIT).
- **args.hxx**: [MIT License](https://opensource.org/licenses/MIT).
- **spdlog**: [MIT License](https://opensource.org/licenses/MIT).
- **ImGUI**: [MIT License](https://opensource.org/licenses/MIT).
- **Vulkan Memory Allocator**: [MIT License](https://opensource.org/licenses/MIT).
- **VkRadixSort**: [MIT License](https://opensource.org/licenses/MIT).
- **implot**: [MIT License](https://opensource.org/licenses/MIT).
- **glfw**: [zlib/libpng license](https://www.glfw.org/license.html).
- **libenvpp**: [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
3 changes: 3 additions & 0 deletions apps/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.26)

add_subdirectory(viewer)
10 changes: 10 additions & 0 deletions apps/viewer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.26)
project(vulkan_splatting_viewer)

add_executable(vulkan_splatting_viewer main.cpp)

target_include_directories(vulkan_splatting_viewer PRIVATE third_party)

target_link_libraries(vulkan_splatting_viewer PRIVATE
libenvpp::libenvpp
vulkan_splatting)
20 changes: 15 additions & 5 deletions main.cpp → apps/viewer/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include <filesystem>
#include <iostream>
#include <libenvpp/env.hpp>

#include "3dgs/Renderer.h"
#include "VulkanSplatting.h"
#include "args.hxx"
#include "spdlog/spdlog.h"

Expand All @@ -21,6 +22,8 @@ int main(int argc, char** argv) {
parser, "immediate-swapchain", "Set swapchain mode to immediate (VK_PRESENT_MODE_IMMEDIATE_KHR)",
{'i', "immediate-swapchain"}
};
args::ValueFlag<uint32_t> widthFlag{parser, "width", "Set window width", {'w', "width"}};
args::ValueFlag<uint32_t> heightFlag{parser, "height", "Set window height", {'h', "height"}};
args::Flag noGuiFlag{parser, "no-gui", "Disable GUI", { "no-gui"}};
args::Positional<std::string> scenePath{parser, "scene", "Path to scene file", "scene.ply"};

Expand Down Expand Up @@ -50,7 +53,7 @@ int main(int argc, char** argv) {
spdlog::set_level(spdlog::level::debug);
}

RendererConfiguration config{
VulkanSplatting::RendererConfiguration config{
envVars.get_or(validationLayers, false),
envVars.get(physicalDeviceId).has_value()
? std::make_optional(envVars.get(physicalDeviceId).value())
Expand Down Expand Up @@ -81,12 +84,19 @@ int main(int argc, char** argv) {
config.enableGui = false;
}

if (widthFlag) {
config.width = args::get(widthFlag);
}

if (heightFlag) {
config.height = args::get(heightFlag);
}

#ifndef DEBUG
try {
#endif
auto renderer = Renderer(config);
renderer.initialize();
renderer.run();
auto renderer = VulkanSplatting(config);
renderer.start();
#ifndef DEBUG
} catch (const std::exception& e) {
spdlog::critical(e.what());
Expand Down
File renamed without changes.
30 changes: 30 additions & 0 deletions include/vulkan_splatting/VulkanSplatting.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef VULKANSPLATTING_H
#define VULKANSPLATTING_H

#include <optional>
#include <string>

class VulkanSplatting {
public:
struct RendererConfiguration {
bool enableVulkanValidationLayers = false;
std::optional<uint8_t> physicalDeviceId = std::nullopt;
bool immediateSwapchain = false;
std::string scene;

float fov = 45.0f;
float near = 0.2f;
float far = 1000.0f;
bool enableGui = true;
uint32_t width = 800;
uint32_t height = 600;
};

explicit VulkanSplatting(RendererConfiguration configuration) : configuration(configuration) {}

void start() const;
private:
RendererConfiguration configuration;
};

#endif //VULKANSPLATTING_H
Loading

0 comments on commit 473818d

Please sign in to comment.