Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions fvdb/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ __all__ = [
"GaussianSplat3d",
"ProjectedGaussianSplats",
"ConvolutionPlan",
"ProjectionType",
"ShOrderingMode",
"Grid",
# JaggedTensor operations
"jcat",
Expand Down
51 changes: 49 additions & 2 deletions fvdb/_fvdb_cpp.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,21 @@ class GaussianSplat3d:
eps_2d: float = ...,
antialias: bool = ...,
) -> tuple[torch.Tensor, torch.Tensor]: ...
def render_depths_sparse(
self,
pixels_to_render: JaggedTensor,
world_to_camera_matrices: torch.Tensor,
projection_matrices: torch.Tensor,
image_width: int,
image_height: int,
near: float,
far: float,
projection_type: ProjectionType = ...,
tile_size: int = ...,
min_radius_2d: float = ...,
eps_2d: float = ...,
antialias: bool = ...,
) -> tuple[JaggedTensor, JaggedTensor]: ...
def render_from_projected_gaussians(
self,
projected_gaussians: ProjectedGaussianSplats,
Expand All @@ -190,6 +205,22 @@ class GaussianSplat3d:
eps_2d: float = ...,
antialias: bool = ...,
) -> tuple[torch.Tensor, torch.Tensor]: ...
def render_images_sparse(
self,
pixels_to_render: JaggedTensor,
world_to_camera_matrices: torch.Tensor,
projection_matrices: torch.Tensor,
image_width: int,
image_height: int,
near: float,
far: float,
projection_type: ProjectionType = ...,
sh_degree_to_use: int = ...,
tile_size: int = ...,
min_radius_2d: float = ...,
eps_2d: float = ...,
antialias: bool = ...,
) -> tuple[JaggedTensor, JaggedTensor]: ...
def render_images_and_depths(
self,
world_to_camera_matrices: torch.Tensor,
Expand All @@ -205,6 +236,22 @@ class GaussianSplat3d:
eps_2d: float = ...,
antialias: bool = ...,
) -> tuple[torch.Tensor, torch.Tensor]: ...
def render_images_and_depths_sparse(
self,
pixels_to_render: JaggedTensor,
world_to_camera_matrices: torch.Tensor,
projection_matrices: torch.Tensor,
image_width: int,
image_height: int,
near: float,
far: float,
projection_type: ProjectionType = ...,
sh_degree_to_use: int = ...,
tile_size: int = ...,
min_radius_2d: float = ...,
eps_2d: float = ...,
antialias: bool = ...,
) -> tuple[JaggedTensor, JaggedTensor]: ...
def render_num_contributing_gaussians(
self,
world_to_camera_matrices: torch.Tensor,
Expand All @@ -219,7 +266,7 @@ class GaussianSplat3d:
eps_2d: float = ...,
antialias: bool = ...,
) -> tuple[torch.Tensor, torch.Tensor]: ...
def sparse_render_num_contributing_gaussians(
def render_num_contributing_gaussians_sparse(
self,
pixels_to_render: JaggedTensor,
world_to_camera_matrices: torch.Tensor,
Expand Down Expand Up @@ -249,7 +296,7 @@ class GaussianSplat3d:
eps_2d: float = ...,
antialias: bool = ...,
) -> tuple[torch.Tensor, torch.Tensor]: ...
def sparse_render_top_contributing_gaussian_ids(
def render_top_contributing_gaussian_ids_sparse(
self,
pixels_to_render: JaggedTensor,
num_samples: int,
Expand Down
302 changes: 295 additions & 7 deletions fvdb/gaussian_splatting.py

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ set(FVDB_CPP_FILES
fvdb/detail/autograd/Attention.cpp
fvdb/detail/autograd/AvgPoolGrid.cpp
fvdb/detail/autograd/EvaluateSphericalHarmonics.cpp
fvdb/detail/autograd/GaussianRender.cpp
fvdb/detail/autograd/Inject.cpp
fvdb/detail/autograd/GaussianProjection.cpp
fvdb/detail/autograd/GaussianRasterize.cpp
fvdb/detail/autograd/GaussianRasterizeSparse.cpp
fvdb/detail/autograd/JaggedReduce.cpp
fvdb/detail/autograd/MaxPoolGrid.cpp
fvdb/detail/autograd/ReadFromDense.cpp
Expand Down
132 changes: 131 additions & 1 deletion src/fvdb/GaussianSplat3d.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
//
#include <fvdb/detail/autograd/GaussianRasterizeSparse.h>

#include <fvdb/GaussianSplat3d.h>
#include <fvdb/detail/io/GaussianPlyIO.h>
#include <fvdb/detail/utils/Nvtx.h>

// Autograd headers
#include <fvdb/detail/autograd/EvaluateSphericalHarmonics.h>
#include <fvdb/detail/autograd/GaussianRender.h>
#include <fvdb/detail/autograd/GaussianProjection.h>
#include <fvdb/detail/autograd/GaussianRasterize.h>

// Ops headers
#include <fvdb/detail/ops/gsplat/GaussianRasterizeNumContributingGaussians.h>
Expand Down Expand Up @@ -440,6 +443,47 @@ GaussianSplat3d::renderImpl(const torch::Tensor &worldToCameraMatrices,
state, settings.tileSize, settings.imageWidth, settings.imageHeight, 0, 0);
}

std::tuple<JaggedTensor, JaggedTensor>
GaussianSplat3d::sparseRenderImpl(const JaggedTensor &pixelsToRender,
const torch::Tensor &worldToCameraMatrices,
const torch::Tensor &projectionMatrices,
const fvdb::detail::ops::RenderSettings &settings) {
FVDB_FUNC_RANGE();

const ProjectedGaussianSplats &state =
projectGaussiansImpl(worldToCameraMatrices, projectionMatrices, settings);

const auto [activeTiles, activeTileMask, tilePixelMask, tilePixelCumsum, pixelMap] =
fvdb::detail::ops::computeSparseInfo(settings.tileSize,
state.tileOffsets.size(2),
state.tileOffsets.size(1),
pixelsToRender);

auto rasterizeResult =
detail::autograd::RasterizeGaussiansToPixelsSparse::apply(pixelsToRender,
state.perGaussian2dMean,
state.perGaussianConic,
state.perGaussianRenderQuantity,
state.perGaussianOpacity,
settings.imageWidth,
settings.imageHeight,
0,
0,
settings.tileSize,
state.tileOffsets,
state.tileGaussianIds,
activeTiles,
tilePixelMask,
tilePixelCumsum,
pixelMap,
false);
auto renderedPixelsJData = rasterizeResult[0];

auto renderedAlphasJData = rasterizeResult[1];
return {pixelsToRender.jagged_like(renderedPixelsJData),
pixelsToRender.jagged_like(renderedAlphasJData)};
}

std::tuple<torch::Tensor, torch::Tensor>
GaussianSplat3d::renderNumContributingGaussiansImpl(
const torch::Tensor &worldToCameraMatrices,
Expand Down Expand Up @@ -762,6 +806,92 @@ GaussianSplat3d::renderNumContributingGaussians(const torch::Tensor &worldToCame
return renderNumContributingGaussiansImpl(worldToCameraMatrices, projectionMatrices, settings);
}

std::tuple<JaggedTensor, JaggedTensor>
GaussianSplat3d::sparseRenderDepths(const fvdb::JaggedTensor &pixelsToRender,
const torch::Tensor &worldToCameraMatrices,
const torch::Tensor &projectionMatrices,
const size_t imageWidth,
const size_t imageHeight,
const float near,
const float far,
const ProjectionType projectionType,
const size_t tileSize,
const float minRadius2d,
const float eps2d,
const bool antialias) {
RenderSettings settings;
settings.imageWidth = imageWidth;
settings.imageHeight = imageHeight;
settings.nearPlane = near;
settings.farPlane = far;
settings.projectionType = projectionType;
settings.shDegreeToUse = 0;
settings.tileSize = tileSize;
settings.radiusClip = minRadius2d;
settings.eps2d = eps2d;
settings.renderMode = RenderSettings::RenderMode::DEPTH;

return sparseRenderImpl(pixelsToRender, worldToCameraMatrices, projectionMatrices, settings);
}

std::tuple<JaggedTensor, JaggedTensor>
GaussianSplat3d::sparseRenderImages(const fvdb::JaggedTensor &pixelsToRender,
const torch::Tensor &worldToCameraMatrices,
const torch::Tensor &projectionMatrices,
const size_t imageWidth,
const size_t imageHeight,
const float near,
const float far,
const ProjectionType projectionType,
const int64_t shDegreeToUse,
const size_t tileSize,
const float minRadius2d,
const float eps2d,
const bool antialias) {
RenderSettings settings;
settings.imageWidth = imageWidth;
settings.imageHeight = imageHeight;
settings.nearPlane = near;
settings.farPlane = far;
settings.projectionType = projectionType;
settings.shDegreeToUse = shDegreeToUse;
settings.tileSize = tileSize;
settings.radiusClip = minRadius2d;
settings.eps2d = eps2d;
settings.renderMode = RenderSettings::RenderMode::RGB;

return sparseRenderImpl(pixelsToRender, worldToCameraMatrices, projectionMatrices, settings);
}

std::tuple<JaggedTensor, JaggedTensor>
GaussianSplat3d::sparseRenderImagesAndDepths(const fvdb::JaggedTensor &pixelsToRender,
const torch::Tensor &worldToCameraMatrices,
const torch::Tensor &projectionMatrices,
const size_t imageWidth,
const size_t imageHeight,
const float near,
const float far,
const ProjectionType projectionType,
const int64_t shDegreeToUse,
const size_t tileSize,
const float minRadius2d,
const float eps2d,
const bool antialias) {
RenderSettings settings;
settings.imageWidth = imageWidth;
settings.imageHeight = imageHeight;
settings.nearPlane = near;
settings.farPlane = far;
settings.projectionType = projectionType;
settings.shDegreeToUse = shDegreeToUse;
settings.tileSize = tileSize;
settings.radiusClip = minRadius2d;
settings.eps2d = eps2d;
settings.renderMode = RenderSettings::RenderMode::RGBD;

return sparseRenderImpl(pixelsToRender, worldToCameraMatrices, projectionMatrices, settings);
}

std::tuple<fvdb::JaggedTensor, fvdb::JaggedTensor>
GaussianSplat3d::sparseRenderNumContributingGaussians(const fvdb::JaggedTensor &pixelsToRender,
const torch::Tensor &worldToCameraMatrices,
Expand Down
64 changes: 61 additions & 3 deletions src/fvdb/GaussianSplat3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,50 @@ class GaussianSplat3d {
const float eps2d = 0.3,
const bool antialias = false);

std::tuple<JaggedTensor, JaggedTensor>
sparseRenderImages(const fvdb::JaggedTensor &pixelsToRender,
const torch::Tensor &worldToCameraMatrices,
const torch::Tensor &projectionMatrices,
const size_t imageWidth,
const size_t imageHeight,
const float near,
const float far,
const ProjectionType projectionType = ProjectionType::PERSPECTIVE,
const int64_t shDegreeToUse = -1,
const size_t tileSize = 16,
const float minRadius2d = 0.0,
const float eps2d = 0.3,
const bool antialias = false);

std::tuple<JaggedTensor, JaggedTensor>
sparseRenderDepths(const fvdb::JaggedTensor &pixelsToRender,
const torch::Tensor &worldToCameraMatrices,
const torch::Tensor &projectionMatrices,
const size_t imageWidth,
const size_t imageHeight,
const float near,
const float far,
const ProjectionType projectionType = ProjectionType::PERSPECTIVE,
const size_t tileSize = 16,
const float minRadius2d = 0.0,
const float eps2d = 0.3,
const bool antialias = false);

std::tuple<JaggedTensor, JaggedTensor>
sparseRenderImagesAndDepths(const fvdb::JaggedTensor &pixelsToRender,
const torch::Tensor &worldToCameraMatrices,
const torch::Tensor &projectionMatrices,
const size_t imageWidth,
const size_t imageHeight,
const float near,
const float far,
const ProjectionType projectionType = ProjectionType::PERSPECTIVE,
const int64_t shDegreeToUse = -1,
const size_t tileSize = 16,
const float minRadius2d = 0.0,
const float eps2d = 0.3,
const bool antialias = false);

/// @brief Render the number of contributing Gaussians for each pixel in the image.
/// @param worldToCameraMatrices [C, 4, 4] Camera-to-world matrices
/// @param projectionMatrices [C, 4, 4] Projection matrices
Expand Down Expand Up @@ -1154,9 +1198,9 @@ class GaussianSplat3d {
/// The mask must have the same length as the number of Gaussians in this scene.
GaussianSplat3d tensorIndexGetImpl(const torch::Tensor &indexOrMask) const;

/// @brief Render the gaussian splatting scene
/// This function returns a single render quantity (RGB, depth, RGB+D) and
/// single alpha value per pixel.
/// @brief Render the scene described by the Gaussian splats from the specified views.
/// This function returns a single render quantity (RGB, depth, RGB+D) and
/// single alpha value per pixel.
/// @param worldToCameraMatrices [C, 4, 4]
/// @param projectionMatrices [C, 3, 3]
/// @param settings
Expand All @@ -1166,6 +1210,20 @@ class GaussianSplat3d {
const torch::Tensor &projectionMatrices,
const fvdb::detail::ops::RenderSettings &settings);

/// @brief Render the scene described by the Gaussian splats at the specified pixels in the
/// specified views. This function returns a single render quantity (RGB, depth, RGB+D)
/// and single alpha value per pixel.
/// @param pixelsToRender [P1 + P2 + ..., 2] JaggedTensor of pixels per camera to render.
/// @param worldToCameraMatrices [C, 4, 4]
/// @param projectionMatrices [C, 3, 3]
/// @param settings
/// @return Tuple of (render quantity, alpha value)
std::tuple<JaggedTensor, JaggedTensor>
sparseRenderImpl(const JaggedTensor &pixelsToRender,
const torch::Tensor &worldToCameraMatrices,
const torch::Tensor &projectionMatrices,
const fvdb::detail::ops::RenderSettings &settings);

/// @brief Render the number of contributing Gaussians for each pixel in the image.
/// @param worldToCameraMatrices [C, 4, 4]
/// @param projectionMatrices [C, 3, 3]
Expand Down
Loading
Loading