导入
渲染概述
学习渲染的基础知识,以及如何使渲染过程可微分,以应用于机器学习。
...
光栅化中的可见性问题
...
光栅化中的Z缓冲
...
PyTorch3D中的可微渲染架构
...
软聚合示意图
1from typing import Union 2 3from pytorch3d.renderer import ( 4 RasterizationSettings, 5 MeshRenderer, 6 MeshRasterizer, 7 SoftPhongShader 8) 9 10def create_renderer( 11 img_dims: Union[int, tuple[int, int]], 12 blur_radius: float, 13 faces_per_pixel: int 14) -> MeshRenderer: 15 """ 16 创建一个MeshRenderer实例 17 18 参数: 19 img_dims: 要生成图像的尺寸 20 blur_radius: 多边形面片模糊的半径 21 faces_per_pixel: 每个像素参与贡献的面片数量 22 """ 23 raster_settings_diff = RasterizationSettings( 24 image_size=img_dims, 25 blur_radius=blur_radius, 26 faces_per_pixel=faces_per_pixel, 27 ) 28 return MeshRenderer( 29 rasterizer=MeshRasterizer( 30 cameras=cameras, 31 raster_settings=raster_settings_diff 32 ), 33 shader = SoftPhongShader( 34 cameras=cameras, 35 lights=lights 36 ) 37 ) 38 39 40# 图像分辨率 41img_dims = 256 42 43# 非可微情况 44ndif_renderer = create_renderer(img_dims, 0.0, 1) 45images_ndif = ndif_renderer(mesh) 46 47# 可微情况 48diff_renderer = create_renderer(img_dims, np.log(1. / 1e-4 - 1.) * 1e-4, 20) 49images_diff = diff_renderer(mesh) 50 51# 渲染图像 52compare_renders(images_ndif[0, ..., :3].numpy(), images_diff[0, ..., :3].numpy(), 53 title_1='非可微情况', title_2='可微情况')
1# 设置渲染器 2raster_settings_diff = RasterizationSettings( 3 image_size=256, 4 blur_radius=np.log(1. / 1e-4 - 1.) * 1e-4, 5 faces_per_pixel=20, 6) 7diff_renderer = MeshRenderer( 8 rasterizer=MeshRasterizer( 9 cameras=cameras, 10 raster_settings=raster_settings_diff 11 ), 12 shader=SoftSilhouetteShader() 13) 14 15# 渲染中性姿态下的图像 16images_neutral = diff_renderer(mesh) 17 18# 渲染偏移后的姿态 19T_offset = torch.full(T.shape, 0.5, requires_grad=True) 20cameras_shifted = FoVPerspectiveCameras(R=R, T=T + T_offset) 21images_shifted = diff_renderer(mesh, cameras=cameras_shifted) 22 23# 显示渲染结果 24compare_renders(images_neutral[0, ..., 3].numpy(), images_shifted[0, ..., 3].detach().numpy(), 25 title_1='中性姿态', title_2='偏移后') 26 27# 创建优化器 28optimizer = torch.optim.SGD([T_offset], lr=1.0, momentum=0.9) 29 30# 计算损失 31optimizer.zero_grad() 32loss = torch.mean((images_neutral[...,-1] - images_shifted[..., -1]) ** 2) 33loss.backward() 34print(T_offset.grad) 35optimizer.step()