Skip to content

Commit

Permalink
3D gaussians
Browse files Browse the repository at this point in the history
  • Loading branch information
Meakk committed Feb 3, 2024
1 parent 10881c9 commit a2043de
Show file tree
Hide file tree
Showing 33 changed files with 994 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[codespell]
skip = ./testing/**/*,./.git/**/*,./**/*.patch,./external/cxxopts/cxxopts.hpp,./external/nlohmann_json/nlohmann/json.hpp
ignore-words-list=nnumber,unknwn,dota,modle
ignore-words-list=nnumber,unknwn,dota,modle,inout
2 changes: 1 addition & 1 deletion .github/actions/vtk_commit_sha
Original file line number Diff line number Diff line change
@@ -1 +1 @@
a4cb9c6c90c18a31e225aa4a18df6a591bf8cd3b
be69fa3a50de292857e69702885576ac6f114805
1 change: 1 addition & 0 deletions application/F3DOptionsParser.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ void ConfigurationOptions::GetOptions(F3DAppOptions& appOptions, f3d::options& o

auto grp2 = cxxOptions.add_options("Material");
this->DeclareOption(grp2, "point-sprites", "o", "Show sphere sprites instead of geometry", options.getAsBoolRef("model.point-sprites.enable"), HasDefault::YES, MayHaveConfig::YES);
this->DeclareOption(grp2, "point-type", "", "Point splat type when showing point sprites", options.getAsStringRef("render.splat-type"), HasDefault::YES, MayHaveConfig::YES, "<sphere|gaussian>");
this->DeclareOption(grp2, "point-size", "", "Point size when showing vertices or point sprites", options.getAsDoubleRef("render.point-size"), HasDefault::YES, MayHaveConfig::YES, "<size>");
this->DeclareOption(grp2, "line-width", "", "Line width when showing edges", options.getAsDoubleRef("render.line-width"), HasDefault::YES, MayHaveConfig::YES, "<width>");
this->DeclareOption(grp2, "color", "", "Solid color", options.getAsDoubleVectorRef("model.color.rgb"), HasDefault::YES, MayHaveConfig::YES, "<R,G,B>");
Expand Down
7 changes: 7 additions & 0 deletions application/testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ else()
endif()
endif()

# Needs splat sorting with compute shaders
if(VTK_VERSION VERSION_GREATER_EQUAL 9.3.20240202)
if(NOT APPLE) # MacOS does not support compute shaders
f3d_test(NAME Test3DGaussiansSplatting DATA small.splat ARGS -osy --up=-Y --point-size=1 --point-type=gaussian --camera-position=-3.6,0.5,-4.2)
endif()
endif()

if (NOT APPLE)
# This test is broken on apple because of #792
f3d_test(NAME TestScalarsCell DATA f3d.vtp ARGS --scalars --cells --comp=-2 --up=+Z DEFAULT_LIGHTS)
Expand Down
19 changes: 19 additions & 0 deletions library/VTKExtensions/Applicative/Testing/TestF3DObjectFactory.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,20 @@
#include <vtkTestUtilities.h>
#include <vtkVersion.h>

#if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240202)
#include "vtkF3DPointSplatMapper.h"
#endif

int TestF3DObjectFactory(int argc, char* argv[])
{
vtkNew<vtkF3DObjectFactory> factory;
vtkObjectFactory::RegisterFactory(factory);
vtkObjectFactory::SetAllEnableFlags(0, "vtkPolyDataMapper", "vtkOpenGLPolyDataMapper");

#if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240202)
vtkObjectFactory::SetAllEnableFlags(0, "vtkPointGaussianMapper", "vtkOpenGLPointGaussianMapper");
#endif

// Check factory utility methods
if (strcmp(factory->GetVTKSourceVersion(), VTK_SOURCE_VERSION) != 0)
{
Expand All @@ -40,6 +48,17 @@ int TestF3DObjectFactory(int argc, char* argv[])
return EXIT_FAILURE;
}

#if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240202)
vtkNew<vtkPointGaussianMapper> pointMapper;
pointMapper->Print(cout);
vtkF3DPointSplatMapper* pointMapperPtr = vtkF3DPointSplatMapper::SafeDownCast(pointMapper);
if (pointMapperPtr == nullptr)
{
std::cerr << "vtkF3DObjectFactory failed to create a vtkF3DPointSplatMapper" << std::endl;
return EXIT_FAILURE;
}
#endif

vtkNew<vtkOutputWindow> window;
#if F3D_WINDOWS_GUI
vtkF3DWin32OutputWindow* windowPtr = vtkF3DWin32OutputWindow::SafeDownCast(window);
Expand Down
20 changes: 18 additions & 2 deletions library/VTKExtensions/Applicative/vtkF3DObjectFactory.cxx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
#include "vtkF3DObjectFactory.h"

#include <vtkVersion.h>

#include "vtkF3DConfigure.h"
#include "vtkF3DPolyDataMapper.h"

#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && \
VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240202)
#include "vtkF3DPointSplatMapper.h"
#endif

#ifdef __ANDROID__
#include "vtkF3DAndroidLogOutputWindow.h"
#elif F3D_WINDOWS_GUI
Expand All @@ -16,13 +23,16 @@
#include "vtkSDL2RenderWindowInteractor.h"
#endif

#include <vtkVersion.h>

vtkStandardNewMacro(vtkF3DObjectFactory);

// Now create the functions to create overrides with.
VTK_CREATE_CREATE_FUNCTION(vtkF3DPolyDataMapper)

#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && \
VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240202)
VTK_CREATE_CREATE_FUNCTION(vtkF3DPointSplatMapper)
#endif

#ifdef __ANDROID__
VTK_CREATE_CREATE_FUNCTION(vtkF3DAndroidLogOutputWindow)
#elif F3D_WINDOWS_GUI
Expand All @@ -42,6 +52,12 @@ vtkF3DObjectFactory::vtkF3DObjectFactory()
this->RegisterOverride("vtkPolyDataMapper", "vtkF3DPolyDataMapper",
"vtkPolyDataMapper override for F3D", 1, vtkObjectFactoryCreatevtkF3DPolyDataMapper);

#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && \
VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240202)
this->RegisterOverride("vtkPointGaussianMapper", "vtkF3DPointSplatMapper",
"vtkPointGaussianMapper override for F3D", 1, vtkObjectFactoryCreatevtkF3DPointSplatMapper);
#endif

#ifdef __ANDROID__
this->RegisterOverride("vtkOutputWindow", "vtkF3DAndroidLogOutputWindow",
"vtkOutputWindow override for F3D", 1, vtkObjectFactoryCreatevtkF3DAndroidLogOutputWindow);
Expand Down
11 changes: 0 additions & 11 deletions library/VTKExtensions/Readers/vtkF3DGenericImporter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,6 @@ struct ReaderPipeline
this->GeometryActor->GetProperty()->SetInterpolationToPBR();
this->VolumeMapper->SetRequestedRenderModeToGPU();
this->PolyDataMapper->InterpolateScalarsBeforeMappingOn();
this->PointGaussianMapper->EmissiveOff();
this->PointGaussianMapper->SetSplatShaderCode(
"//VTK::Color::Impl\n"
"float dist = dot(offsetVCVSOutput.xy, offsetVCVSOutput.xy);\n"
"if (dist > 1.0) {\n"
" discard;\n"
"} else {\n"
" float scale = (1.0 - dist);\n"
" ambientColor *= scale;\n"
" diffuseColor *= scale;\n"
"}\n");
}

std::string Name;
Expand Down
26 changes: 25 additions & 1 deletion library/VTKExtensions/Rendering/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,25 @@ set(sources
set(private_headers
${CMAKE_CURRENT_BINARY_DIR}/F3DDefaultHDRI.h)

set(shader_files
glsl/vtkF3DBitonicSortGlobalDisperseCS.glsl
glsl/vtkF3DBitonicSortGlobalFlipCS.glsl
glsl/vtkF3DBitonicSortLocalDisperseCS.glsl
glsl/vtkF3DBitonicSortLocalSortCS.glsl
glsl/vtkF3DBitonicSortFunctions.glsl
glsl/vtkF3DComputeDepthCS.glsl)

foreach(file IN LISTS shader_files)
vtk_encode_string(
INPUT "${file}"
HEADER_OUTPUT header
SOURCE_OUTPUT source)
list(APPEND sources
"${source}")
list(APPEND private_headers
"${header}")
endforeach()

set(classes
vtkF3DCachedLUTTexture
vtkF3DCachedSpecularTexture
Expand All @@ -25,8 +44,13 @@ set(classes
vtkF3DRendererWithColoring
)

# Needs https://gitlab.kitware.com/vtk/vtk/-/merge_requests/10675
if(NOT ANDROID AND NOT EMSCRIPTEN AND VTK_VERSION VERSION_GREATER_EQUAL 9.3.20240202)
set(classes ${classes} vtkF3DBitonicSort vtkF3DPointSplatMapper)
endif()

if(NOT VTK_VERSION VERSION_GREATER_EQUAL 9.2.20220907)
set(classes ${classes} vtkF3DOrientationMarkerWidget)
set(classes ${classes} vtkF3DOrientationMarkerWidget)
endif()

vtk_module_add_module(f3d::VTKExtensionsRendering
Expand Down
21 changes: 16 additions & 5 deletions library/VTKExtensions/Rendering/Testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@ if(VTK_VERSION VERSION_LESS_EQUAL 9.1.0)
cmake_policy(SET CMP0115 OLD)
endif()

list(APPEND VTKExtensionsRenderingTests_list
TestF3DInteractorEventRecorder.cxx
TestF3DOpenGLGridMapper.cxx
TestF3DRenderPass.cxx
TestF3DRendererWithColoring.cxx
TestF3DCachedTexturesPrint.cxx
)

# Compute shaders are not supported on mac
# Also needs https://gitlab.kitware.com/vtk/vtk/-/merge_requests/10675
if(NOT ANDROID AND NOT EMSCRIPTEN AND VTK_VERSION VERSION_GREATER_EQUAL 9.3.20240202)
list(APPEND VTKExtensionsRenderingTests_list
TestF3DBitonicSort.cxx)
endif()

vtk_add_test_cxx(VTKExtensionsRenderingTests tests
NO_DATA NO_VALID NO_OUTPUT
TestF3DInteractorEventRecorder.cxx
TestF3DOpenGLGridMapper.cxx
TestF3DRenderPass.cxx
TestF3DRendererWithColoring.cxx
TestF3DCachedTexturesPrint.cxx
${VTKExtensionsRenderingTests_list}
${F3D_SOURCE_DIR}/testing/ ${CMAKE_BINARY_DIR}/Testing/Temporary/)
vtk_test_cxx_executable(VTKExtensionsRenderingTests tests)
68 changes: 68 additions & 0 deletions library/VTKExtensions/Rendering/Testing/TestF3DBitonicSort.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <vtkOpenGLBufferObject.h>
#include <vtkOpenGLRenderWindow.h>
#include <vtkShader.h>

#include "vtkF3DBitonicSort.h"

#include "vtkF3DBitonicSortFunctions.h"
#include "vtkF3DBitonicSortGlobalDisperseCS.h"
#include "vtkF3DBitonicSortGlobalFlipCS.h"
#include "vtkF3DBitonicSortLocalDisperseCS.h"
#include "vtkF3DBitonicSortLocalSortCS.h"

#include <algorithm>
#include <random>
#include <sstream>

int TestF3DBitonicSort(int argc, char* argv[])
{
// we need an OpenGL context
vtkNew<vtkRenderWindow> renWin;
renWin->OffScreenRenderingOn();
renWin->Start();

if (!vtkShader::IsComputeShaderSupported())
{
std::cerr << "Compute shaders are not supported on this system, skipping the test.\n";
return EXIT_SUCCESS;
}

constexpr int nbElements = 10000;

// fill CPU keys and values buffers
std::vector<double> keys(nbElements);
std::vector<int> values(nbElements);

std::random_device dev;
std::mt19937 rng(dev());
std::uniform_real_distribution<double> dist(0.0, 1.0);

std::generate(std::begin(keys), std::end(keys), [&]() { return dist(rng); });
std::fill(std::begin(values), std::end(values), 0); // we do not care about the values

// upload these buffers to the GPU
vtkNew<vtkOpenGLBufferObject> bufferKeys;
vtkNew<vtkOpenGLBufferObject> bufferValues;

bufferKeys->Upload(keys, vtkOpenGLBufferObject::ArrayBuffer);
bufferValues->Upload(values, vtkOpenGLBufferObject::ArrayBuffer);

// sort
vtkNew<vtkF3DBitonicSort> sorter;
sorter->Initialize(128, VTK_DOUBLE, VTK_INT);
sorter->Run(vtkOpenGLRenderWindow::SafeDownCast(renWin), nbElements, bufferKeys, bufferValues);

// download sorted key buffer to CPU
bufferKeys->Download(keys.data(), keys.size());

// check if correctly sorted
for (int i = 1; i < nbElements; i++)
{
if (keys[i - 1] > keys[i])
{
return EXIT_FAILURE;
}
}

return EXIT_SUCCESS;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
ivec2 disperse(uint t, uint h)
{
uint q = (t / h) * 2 * h;

uint x = q + t % h;
uint y = q + t % h + h;

return ivec2(x, y);
}

ivec2 flip(uint t, uint h)
{
uint q = (t / h) * 2 * h;

uint x = q + t % h;
uint y = q + 2 * h - (t % h) - 1;

return ivec2(x, y);
}

void swap_key(inout KeyType key1, inout KeyType key2)
{
KeyType tmp = key1;
key1 = key2;
key2 = tmp;
}

void swap_value(inout ValueType value1, inout ValueType value2)
{
ValueType tmp = value1;
value1 = value2;
value2 = tmp;
}

void compare_and_swap(ivec2 idx)
{
if (key[idx.x] > key[idx.y] && idx.y < count)
{
swap_key(key[idx.x], key[idx.y]);
swap_value(value[idx.x], value[idx.y]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#version 430

//VTK::BitonicDefines::Dec

layout(local_size_x = WorkgroupSize) in;
layout(std430) buffer;

layout(binding = 0) buffer Keys
{
KeyType key[];
};

layout(binding = 1) buffer Values
{
ValueType value[];
};

layout(location = 0) uniform int count;
layout(location = 1) uniform int height;

//VTK::BitonicFunctions::Dec

void main()
{
compare_and_swap(disperse(gl_GlobalInvocationID.x, height));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#version 430

//VTK::BitonicDefines::Dec

layout(local_size_x = WorkgroupSize) in;
layout(std430) buffer;

layout(binding = 0) buffer Keys
{
KeyType key[];
};

layout(binding = 1) buffer Values
{
ValueType value[];
};

layout(location = 0) uniform int count;
layout(location = 1) uniform int height;

//VTK::BitonicFunctions::Dec

void main()
{
compare_and_swap(flip(gl_GlobalInvocationID.x, height));
}
Loading

0 comments on commit a2043de

Please sign in to comment.