jadechoghari
commited on
Commit
•
a99ee1d
1
Parent(s):
713a07a
Create ray_marcher.py
Browse files- ray_marcher.py +73 -0
ray_marcher.py
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
2 |
+
# All rights reserved.
|
3 |
+
#
|
4 |
+
# This source code is licensed under the license found in the
|
5 |
+
# LICENSE file in the root directory of this source tree.
|
6 |
+
# SPDX-FileCopyrightText: Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
7 |
+
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
8 |
+
#
|
9 |
+
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
10 |
+
# property and proprietary rights in and to this material, related
|
11 |
+
# documentation and any modifications thereto. Any use, reproduction,
|
12 |
+
# disclosure or distribution of this material and related documentation
|
13 |
+
# without an express license agreement from NVIDIA CORPORATION or
|
14 |
+
# its affiliates is strictly prohibited.
|
15 |
+
#
|
16 |
+
# Modified by Zexin He
|
17 |
+
# The modifications are subject to the same license as the original.
|
18 |
+
|
19 |
+
|
20 |
+
"""
|
21 |
+
The ray marcher takes the raw output of the implicit representation and uses the volume rendering equation to produce composited colors and depths.
|
22 |
+
Based off of the implementation in MipNeRF (this one doesn't do any cone tracing though!)
|
23 |
+
"""
|
24 |
+
|
25 |
+
import torch
|
26 |
+
import torch.nn as nn
|
27 |
+
|
28 |
+
|
29 |
+
class MipRayMarcher2(nn.Module):
|
30 |
+
def __init__(self, activation_factory):
|
31 |
+
super().__init__()
|
32 |
+
self.activation_factory = activation_factory
|
33 |
+
|
34 |
+
def run_forward(self, colors, densities, depths, rendering_options):
|
35 |
+
|
36 |
+
deltas = depths[:, :, 1:] - depths[:, :, :-1]
|
37 |
+
colors_mid = (colors[:, :, :-1] + colors[:, :, 1:]) / 2
|
38 |
+
densities_mid = (densities[:, :, :-1] + densities[:, :, 1:]) / 2
|
39 |
+
depths_mid = (depths[:, :, :-1] + depths[:, :, 1:]) / 2
|
40 |
+
|
41 |
+
|
42 |
+
|
43 |
+
# using factory mode for better usability
|
44 |
+
densities_mid = self.activation_factory(rendering_options)(densities_mid)
|
45 |
+
|
46 |
+
density_delta = densities_mid * deltas
|
47 |
+
|
48 |
+
alpha = 1 - torch.exp(-density_delta)
|
49 |
+
|
50 |
+
alpha_shifted = torch.cat([torch.ones_like(alpha[:, :, :1]), 1-alpha + 1e-10], -2)
|
51 |
+
weights = alpha * torch.cumprod(alpha_shifted, -2)[:, :, :-1]
|
52 |
+
|
53 |
+
composite_rgb = torch.sum(weights * colors_mid, -2)
|
54 |
+
weight_total = weights.sum(2)
|
55 |
+
composite_depth = torch.sum(weights * depths_mid, -2) / weight_total
|
56 |
+
|
57 |
+
# clip the composite to min/max range of depths
|
58 |
+
composite_depth = torch.nan_to_num(composite_depth, float('inf'))
|
59 |
+
composite_depth = torch.clamp(composite_depth, torch.min(depths), torch.max(depths))
|
60 |
+
|
61 |
+
if rendering_options.get('white_back', False):
|
62 |
+
composite_rgb = composite_rgb + 1 - weight_total
|
63 |
+
|
64 |
+
# rendered value scale is 0-1, comment out original mipnerf scaling
|
65 |
+
# composite_rgb = composite_rgb * 2 - 1 # Scale to (-1, 1)
|
66 |
+
|
67 |
+
return composite_rgb, composite_depth, weights
|
68 |
+
|
69 |
+
|
70 |
+
def forward(self, colors, densities, depths, rendering_options):
|
71 |
+
composite_rgb, composite_depth, weights = self.run_forward(colors, densities, depths, rendering_options)
|
72 |
+
|
73 |
+
return composite_rgb, composite_depth, weights
|