| """Visibility loss — free tokens only (§2.6 item 5). |
| |
| TokenGS's penalty keeps Gaussians inside >=1 supervision frustum (clipped at |
| 1.0). Applied **only to T^F**: map-anchored tokens get correct positions from |
| the map even with zero rendering gradient, so penalizing them for projecting |
| outside the input views would destroy the extrapolation scaffold (we *want* |
| road geometry beyond the FOV). |
| """ |
|
|
| from __future__ import annotations |
|
|
| import torch |
|
|
| from mapgs.geometry.cameras import project_points |
| from mapgs.geometry.transforms import se3_inverse |
|
|
|
|
| def visibility_loss( |
| means_free: torch.Tensor, |
| K: torch.Tensor, |
| cam2world: torch.Tensor, |
| H: int, |
| W: int, |
| near: float = 0.1, |
| ) -> torch.Tensor: |
| if means_free.shape[0] == 0: |
| return means_free.new_tensor(0.0) |
| w2c = se3_inverse(cam2world) |
| uv, z = project_points(means_free[None].expand(K.shape[0], -1, -1), K, w2c) |
| du = torch.relu(uv[..., 0] - (W - 1)) + torch.relu(-uv[..., 0]) |
| dv = torch.relu(uv[..., 1] - (H - 1)) + torch.relu(-uv[..., 1]) |
| behind = torch.relu(near - z) |
| out_of_view = du / W + dv / H + behind |
| pen = out_of_view.min(dim=0).values |
| return pen.clamp(max=1.0).mean() |
|
|