|
import nvdiffrast.torch as dr |
|
import torch |
|
|
|
from ...utils.typing import * |
|
|
|
|
|
class NVDiffRasterizerContext: |
|
def __init__(self, context_type: str, device: torch.device) -> None: |
|
self.device = device |
|
self.ctx = self.initialize_context(context_type, device) |
|
|
|
def initialize_context( |
|
self, context_type: str, device: torch.device |
|
) -> Union[dr.RasterizeGLContext, dr.RasterizeCudaContext]: |
|
if context_type == "gl": |
|
return dr.RasterizeGLContext(device=device) |
|
elif context_type == "cuda": |
|
return dr.RasterizeCudaContext(device=device) |
|
else: |
|
raise ValueError(f"Unknown rasterizer context type: {context_type}") |
|
|
|
def vertex_transform( |
|
self, verts: Float[Tensor, "Nv 3"], mvp_mtx: Float[Tensor, "B 4 4"] |
|
) -> Float[Tensor, "B Nv 4"]: |
|
verts_homo = torch.cat( |
|
[verts, torch.ones([verts.shape[0], 1]).to(verts)], dim=-1 |
|
) |
|
return torch.matmul(verts_homo, mvp_mtx.permute(0, 2, 1)) |
|
|
|
def rasterize( |
|
self, |
|
pos: Float[Tensor, "B Nv 4"], |
|
tri: Integer[Tensor, "Nf 3"], |
|
resolution: Union[int, Tuple[int, int]], |
|
): |
|
|
|
return dr.rasterize(self.ctx, pos.float(), tri.int(), resolution, grad_db=True) |
|
|
|
def rasterize_one( |
|
self, |
|
pos: Float[Tensor, "Nv 4"], |
|
tri: Integer[Tensor, "Nf 3"], |
|
resolution: Union[int, Tuple[int, int]], |
|
): |
|
|
|
rast, rast_db = self.rasterize(pos[None, ...], tri, resolution) |
|
return rast[0], rast_db[0] |
|
|
|
def antialias( |
|
self, |
|
color: Float[Tensor, "B H W C"], |
|
rast: Float[Tensor, "B H W 4"], |
|
pos: Float[Tensor, "B Nv 4"], |
|
tri: Integer[Tensor, "Nf 3"], |
|
) -> Float[Tensor, "B H W C"]: |
|
return dr.antialias(color.float(), rast, pos.float(), tri.int()) |
|
|
|
def interpolate( |
|
self, |
|
attr: Float[Tensor, "B Nv C"], |
|
rast: Float[Tensor, "B H W 4"], |
|
tri: Integer[Tensor, "Nf 3"], |
|
rast_db=None, |
|
diff_attrs=None, |
|
) -> Float[Tensor, "B H W C"]: |
|
return dr.interpolate( |
|
attr.float(), rast, tri.int(), rast_db=rast_db, diff_attrs=diff_attrs |
|
) |
|
|
|
def interpolate_one( |
|
self, |
|
attr: Float[Tensor, "Nv C"], |
|
rast: Float[Tensor, "B H W 4"], |
|
tri: Integer[Tensor, "Nf 3"], |
|
rast_db=None, |
|
diff_attrs=None, |
|
) -> Float[Tensor, "B H W C"]: |
|
return self.interpolate(attr[None, ...], rast, tri, rast_db, diff_attrs) |
|
|