From 380df50b2a6e46f829225329a469a810e4c18e36 Mon Sep 17 00:00:00 2001 From: Jack Huang Date: Tue, 3 Sep 2024 22:16:43 +0800 Subject: [PATCH 1/5] * correct a typo to fix #373 --- tests/test_basic.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_basic.py b/tests/test_basic.py index b7084ecd0..349329584 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -239,11 +239,11 @@ def test_projection(test_data, fused: bool, calc_compensations: bool, ortho: boo ) # backward - v_means2d = torch.randn_like(means2d) * radii[..., None] - v_depths = torch.randn_like(depths) * radii - v_conics = torch.randn_like(conics) * radii[..., None] + v_means2d = torch.randn_like(means2d) * valid[..., None] + v_depths = torch.randn_like(depths) * valid + v_conics = torch.randn_like(conics) * valid[..., None] if calc_compensations: - v_compensations = torch.randn_like(compensations) * radii + v_compensations = torch.randn_like(compensations) * valid v_viewmats, v_quats, v_scales, v_means = torch.autograd.grad( (means2d * v_means2d).sum() + (depths * v_depths).sum() From e32fb1649f2996768f24becf26f53791e5831310 Mon Sep 17 00:00:00 2001 From: Jack Huang Date: Wed, 9 Oct 2024 18:13:00 +0800 Subject: [PATCH 2/5] * uses AABB to decide if gaussian splat is within view frustrum * corrected the use of 3 sigma in 2D space. the correct interval is +/- 3.4086, since it is a multivariate gaussian distribution --- gsplat/cuda/_torch_impl.py | 21 ++++++++++++------- .../cuda/csrc/fully_fused_projection_fwd.cu | 9 +++++--- .../csrc/fully_fused_projection_packed_fwd.cu | 9 +++++--- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/gsplat/cuda/_torch_impl.py b/gsplat/cuda/_torch_impl.py index 892c6a66f..185180def 100644 --- a/gsplat/cuda/_torch_impl.py +++ b/gsplat/cuda/_torch_impl.py @@ -305,21 +305,28 @@ def _fully_fused_projection( ) # [C, N, 3] depths = means_c[..., 2] # [C, N] - + + # scale factor for 3 sigma in 2 dimension for a 2d multivariate gaussian + # distribution + scale_factor = 3.4086 + # calculating magnitude of major and and minor axis b = (covars2d[..., 0, 0] + covars2d[..., 1, 1]) / 2 # (...,) v1 = b + torch.sqrt(torch.clamp(b**2 - det, min=0.01)) # (...,) - radius = torch.ceil(3.0 * torch.sqrt(v1)) # (...,) + radius = torch.ceil(scale_factor * torch.sqrt(v1)) # (...,) # v2 = b - torch.sqrt(torch.clamp(b**2 - det, min=0.01)) # (...,) - # radius = torch.ceil(3.0 * torch.sqrt(torch.max(v1, v2))) # (...,) + # radius = torch.ceil(scale_factor * torch.sqrt(torch.max(v1, v2))) # (...,) + + x_proj = scale_factor * torch.sqrt(covars2d[..., 0, 0]) # (...,) + y_proj = scale_factor * torch.sqrt(covars2d[..., 1, 1]) # (...,) valid = (det > 0) & (depths > near_plane) & (depths < far_plane) radius[~valid] = 0.0 inside = ( - (means2d[..., 0] + radius > 0) - & (means2d[..., 0] - radius < width) - & (means2d[..., 1] + radius > 0) - & (means2d[..., 1] - radius < height) + (means2d[..., 0] + x_proj > 0) + & (means2d[..., 0] - x_proj < width) + & (means2d[..., 1] + y_proj > 0) + & (means2d[..., 1] - y_proj < height) ) radius[~inside] = 0.0 diff --git a/gsplat/cuda/csrc/fully_fused_projection_fwd.cu b/gsplat/cuda/csrc/fully_fused_projection_fwd.cu index c651e803d..8e70cefc2 100644 --- a/gsplat/cuda/csrc/fully_fused_projection_fwd.cu +++ b/gsplat/cuda/csrc/fully_fused_projection_fwd.cu @@ -162,11 +162,14 @@ __global__ void fully_fused_projection_fwd_kernel( inverse(covar2d, covar2d_inv); // take 3 sigma as the radius (non differentiable) + T scale_factor = 3.4086; T b = 0.5f * (covar2d[0][0] + covar2d[1][1]); T v1 = b + sqrt(max(0.01f, b * b - det)); - T radius = ceil(3.f * sqrt(v1)); + T radius = ceil(scale_factor * sqrt(v1)); // T v2 = b - sqrt(max(0.1f, b * b - det)); // T radius = ceil(3.f * sqrt(max(v1, v2))); + T x_proj = scale_factor * sqrt(covar2d[0][0]); + T y_proj = scale_factor * sqrt(covar2d[1][1]); if (radius <= radius_clip) { radii[idx] = 0; @@ -174,8 +177,8 @@ __global__ void fully_fused_projection_fwd_kernel( } // mask out gaussians outside the image region - if (mean2d.x + radius <= 0 || mean2d.x - radius >= image_width || - mean2d.y + radius <= 0 || mean2d.y - radius >= image_height) { + if (mean2d.x + x_proj <= 0 || mean2d.x - x_proj >= image_width || + mean2d.y + y_proj <= 0 || mean2d.y - y_proj >= image_height) { radii[idx] = 0; return; } diff --git a/gsplat/cuda/csrc/fully_fused_projection_packed_fwd.cu b/gsplat/cuda/csrc/fully_fused_projection_packed_fwd.cu index 4d8609f05..213df79b9 100644 --- a/gsplat/cuda/csrc/fully_fused_projection_packed_fwd.cu +++ b/gsplat/cuda/csrc/fully_fused_projection_packed_fwd.cu @@ -178,18 +178,21 @@ __global__ void fully_fused_projection_packed_fwd_kernel( T radius; if (valid) { // take 3 sigma as the radius (non differentiable) + T scale_factor = 3.4086; T b = 0.5f * (covar2d[0][0] + covar2d[1][1]); T v1 = b + sqrt(max(0.1f, b * b - det)); T v2 = b - sqrt(max(0.1f, b * b - det)); - radius = ceil(3.f * sqrt(max(v1, v2))); + radius = ceil(scale_factor * sqrt(max(v1, v2))); + T x_proj = scale_factor * sqrt(covar2d[0][0]); + T y_proj = scale_factor * sqrt(covar2d[1][1]); if (radius <= radius_clip) { valid = false; } // mask out gaussians outside the image region - if (mean2d.x + radius <= 0 || mean2d.x - radius >= image_width || - mean2d.y + radius <= 0 || mean2d.y - radius >= image_height) { + if (mean2d.x + x_proj <= 0 || mean2d.x - x_proj >= image_width || + mean2d.y + y_proj <= 0 || mean2d.y - y_proj >= image_height) { valid = false; } } From d143f237c60f2ba7e7ecc7452992dcb526fea928 Mon Sep 17 00:00:00 2001 From: Jack Huang Date: Wed, 9 Oct 2024 22:33:57 +0800 Subject: [PATCH 3/5] * fixed trailing space issue --- gsplat/cuda/_torch_impl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsplat/cuda/_torch_impl.py b/gsplat/cuda/_torch_impl.py index 185180def..60d3b5fcc 100644 --- a/gsplat/cuda/_torch_impl.py +++ b/gsplat/cuda/_torch_impl.py @@ -308,7 +308,7 @@ def _fully_fused_projection( # scale factor for 3 sigma in 2 dimension for a 2d multivariate gaussian # distribution - scale_factor = 3.4086 + scale_factor = 3.4086 # calculating magnitude of major and and minor axis b = (covars2d[..., 0, 0] + covars2d[..., 1, 1]) / 2 # (...,) v1 = b + torch.sqrt(torch.clamp(b**2 - det, min=0.01)) # (...,) From 877188cd5372179ae3731c7baa66a4d4663b95fe Mon Sep 17 00:00:00 2001 From: Jack Huang Date: Wed, 9 Oct 2024 22:45:28 +0800 Subject: [PATCH 4/5] * trying to resolve black formatting failure --- gsplat/cuda/_torch_impl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gsplat/cuda/_torch_impl.py b/gsplat/cuda/_torch_impl.py index 60d3b5fcc..6a0c772ee 100644 --- a/gsplat/cuda/_torch_impl.py +++ b/gsplat/cuda/_torch_impl.py @@ -316,8 +316,8 @@ def _fully_fused_projection( # v2 = b - torch.sqrt(torch.clamp(b**2 - det, min=0.01)) # (...,) # radius = torch.ceil(scale_factor * torch.sqrt(torch.max(v1, v2))) # (...,) - x_proj = scale_factor * torch.sqrt(covars2d[..., 0, 0]) # (...,) - y_proj = scale_factor * torch.sqrt(covars2d[..., 1, 1]) # (...,) + x_proj = scale_factor * torch.sqrt(covars2d[..., 0, 0]) # (...,) + y_proj = scale_factor * torch.sqrt(covars2d[..., 1, 1]) # (...,) valid = (det > 0) & (depths > near_plane) & (depths < far_plane) radius[~valid] = 0.0 From e47675757a06f2db963501008dbfeb054f778c66 Mon Sep 17 00:00:00 2001 From: Jack Huang Date: Wed, 9 Oct 2024 23:01:12 +0800 Subject: [PATCH 5/5] * fixing black formatting issues --- gsplat/cuda/_torch_impl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsplat/cuda/_torch_impl.py b/gsplat/cuda/_torch_impl.py index 6a0c772ee..5de19f1f4 100644 --- a/gsplat/cuda/_torch_impl.py +++ b/gsplat/cuda/_torch_impl.py @@ -305,7 +305,7 @@ def _fully_fused_projection( ) # [C, N, 3] depths = means_c[..., 2] # [C, N] - + # scale factor for 3 sigma in 2 dimension for a 2d multivariate gaussian # distribution scale_factor = 3.4086