(sdf_in, trunc, z_vals, sample_mask_per)
| 235 | |
| 236 | # convert sdf to weight |
| 237 | def sdf2weights(sdf_in, trunc, z_vals, sample_mask_per): |
| 238 | weights = torch.sigmoid(sdf_in / trunc) * \ |
| 239 | torch.sigmoid(-sdf_in / trunc) |
| 240 | # use the change of sign to find the surface, sdf's sign changes as it cross the surface |
| 241 | signs = sdf_in[:, 1:] * sdf_in[:, :-1] |
| 242 | mask = torch.where( |
| 243 | signs < 0.0, torch.ones_like(signs), torch.zeros_like(signs) |
| 244 | ) |
| 245 | # return the index of the closest point outside the surface |
| 246 | inds = torch.argmax(mask, axis=1) |
| 247 | inds = inds[..., None] |
| 248 | z_min = torch.gather(z_vals, 1, inds) |
| 249 | # calculate truncation mask, delete the point behind the surface and exceed trunc, z_min is here approximate the surface |
| 250 | mask = torch.where( |
| 251 | z_vals < z_min + trunc, |
| 252 | torch.ones_like(z_vals), |
| 253 | torch.zeros_like(z_vals), |
| 254 | ) |
| 255 | # mask truncation and mask not hit voxel |
| 256 | weights = weights * mask * sample_mask_per |
| 257 | return weights / (torch.sum(weights, dim=-1, keepdims=True) + 1e-8), z_min |
| 258 | |
| 259 | |
| 260 | def render_rays( |
no outgoing calls
no test coverage detected