| from dataclasses import dataclass |
| from typing import Literal |
|
|
| import torch |
| from einops import rearrange, repeat |
| from jaxtyping import Float, Int |
| from torch import Tensor |
|
|
| from ...scene_trainer.gaussian_module import GaussiansModule |
| from ..types import Gaussians |
| from .cuda_splatting_fastgs import ( |
| render_cuda_fastgs, |
| render_depth_cuda_fastgs, |
| render_metric_counts_fastgs, |
| ) |
| from .splatting_cuda_decoder import SplattingCUDADecoder |
|
|
|
|
| @dataclass |
| class FastGSDecoderSplattingCUDACfg: |
| name: Literal["fastgs"] |
| scale_invariant: bool |
| |
| |
| use_covariances: bool = False |
| |
| |
| mult: float = 0.5 |
|
|
|
|
| class FastGSDecoderSplattingCUDA(SplattingCUDADecoder[FastGSDecoderSplattingCUDACfg]): |
| """FastGS diff_gaussian_rasterization_fastgs backend. Only the rasterizer calls differ from |
| the shared base; see splatting_cuda_decoder.SplattingCUDADecoder for the orchestration.""" |
|
|
| def _produces_abs_grad(self) -> bool: |
| |
| return True |
|
|
| def _raster(self, ext, intr, near, far, image_shape, bg, means, covars, shs, opacities, |
| scales, rotations_wxyz, means2d_out, means2d_abs_out=None): |
| return render_cuda_fastgs( |
| ext, intr, near, far, image_shape, bg, means, covars, shs, opacities, |
| scale_invariant=self.cfg.scale_invariant, |
| gaussian_scales=scales, |
| gaussian_rotations=rotations_wxyz, |
| mult=self.cfg.mult, |
| means2d_out=means2d_out, |
| means2d_abs_out=means2d_abs_out, |
| ) |
|
|
| def _raster_depth(self, ext, intr, near, far, image_shape, means, covars, opacities, mode): |
| return render_depth_cuda_fastgs( |
| ext, intr, near, far, image_shape, means, covars, opacities, |
| mode=mode, scale_invariant=self.cfg.scale_invariant, mult=self.cfg.mult, |
| ) |
|
|
| @torch.no_grad() |
| def render_metric_counts( |
| self, |
| gaussians: Gaussians | GaussiansModule, |
| extrinsics: Float[Tensor, "batch view 4 4"], |
| intrinsics: Float[Tensor, "batch view 3 3"], |
| near: Float[Tensor, "batch view"], |
| far: Float[Tensor, "batch view"], |
| image_shape: tuple[int, int], |
| metric_maps: Int[Tensor, "view height_width"], |
| ) -> Int[Tensor, "view gaussian"]: |
| """FastGS multi-view importance signal: per-view per-Gaussian counts of flagged (high-error) |
| pixels each Gaussian contributed to. Assumes batch size 1; ``metric_maps`` has one flattened |
| [H*W] map per view. Reduce with ``adc.fastgs.compute_fastgs_scores``.""" |
| b, v, _, _ = extrinsics.shape |
| assert b == 1, "render_metric_counts assumes scene batch size 1" |
| means, shs, opacities, scales, rotations_wxyz, covars = self._prepare_flat_gaussians(gaussians, b, v) |
| bg = repeat(self.background_color, "c -> (b v) c", b=b, v=v) |
| return render_metric_counts_fastgs( |
| rearrange(extrinsics, "b v i j -> (b v) i j"), |
| rearrange(intrinsics, "b v i j -> (b v) i j"), |
| rearrange(near, "b v -> (b v)"), |
| rearrange(far, "b v -> (b v)"), |
| image_shape, bg, means, |
| covars, |
| shs, opacities, metric_maps, |
| scale_invariant=self.cfg.scale_invariant, |
| gaussian_scales=scales, |
| gaussian_rotations=rotations_wxyz, |
| mult=self.cfg.mult, |
| ) |
|
|