diff --git a/arguments/__init__.py b/arguments/__init__.py index 4238f73..b15a16d 100644 --- a/arguments/__init__.py +++ b/arguments/__init__.py @@ -61,7 +61,7 @@ class ModelParams(ParamGroup): def extract(self, args): ''' 从args对象中提取出与 ModelParams类中定义的参数相匹配的值,并将它们封装到一个新的 GroupParams 对象中 - args: 存储着 命令行和main中预设的参数 + args: 存储着 命令行和main中预设的参数 ''' g = super().extract(args) # 返回的GroupParams对象 g.source_path = os.path.abspath(g.source_path) # 更新为绝对路径 diff --git a/gaussian_renderer/__init__.py b/gaussian_renderer/__init__.py index eed5713..8aa25a7 100644 --- a/gaussian_renderer/__init__.py +++ b/gaussian_renderer/__init__.py @@ -17,22 +17,30 @@ from utils.sh_utils import eval_sh def render(viewpoint_camera, pc : GaussianModel, pipe, bg_color : torch.Tensor, scaling_modifier = 1.0, override_color = None): """ - Render the scene. - - Background tensor (bg_color) must be on GPU! + 渲染场景: 将高斯分布的点投影到2D屏幕上来生成渲染图像 + viewpoint_camera: 训练相机集合 + pc: 高斯模型 + pipe: 管道相关参数 + bg_color: Background tensor 必须 on GPU + scaling_modifier: + override_color: """ # Create zero tensor. We will use it to make pytorch return gradients of the 2D (screen-space) means + # 创建一个与输入点云(高斯模型)大小相同的 零tensor,用于记录屏幕空间中的点的位置。这个张量将用于计算对于屏幕空间坐标的梯度 screenspace_points = torch.zeros_like(pc.get_xyz, dtype=pc.get_xyz.dtype, requires_grad=True, device="cuda") + 0 try: + # 尝试保留张量的梯度。这是为了确保可以在反向传播过程中计算对于屏幕空间坐标的梯度 screenspace_points.retain_grad() except: pass # Set up rasterization configuration + # 计算视场的 tan 值,这将用于设置光栅化配置 tanfovx = math.tan(viewpoint_camera.FoVx * 0.5) tanfovy = math.tan(viewpoint_camera.FoVy * 0.5) + # 设置光栅化的配置,包括图像的大小、视场的 tan 值、背景颜色、视图矩阵viewmatrix、投影矩阵projmatrix等 raster_settings = GaussianRasterizationSettings( image_height=int(viewpoint_camera.image_height), image_width=int(viewpoint_camera.image_width), @@ -45,18 +53,19 @@ def render(viewpoint_camera, pc : GaussianModel, pipe, bg_color : torch.Tensor, sh_degree=pc.active_sh_degree, campos=viewpoint_camera.camera_center, prefiltered=False, - debug=pipe.debug, - clamp_color=True + debug=pipe.debug ) + # 创建一个高斯光栅化器对象,用于将高斯分布投影到屏幕上 rasterizer = GaussianRasterizer(raster_settings=raster_settings) + # 获取高斯模型的三维坐标、屏幕空间坐标、透明度 means3D = pc.get_xyz means2D = screenspace_points opacity = pc.get_opacity - # If precomputed 3d covariance is provided, use it. If not, then it will be computed from - # scaling / rotation by the rasterizer. + # If precomputed 3d covariance is provided, use it. If not, then it will be computed from scaling / rotation by the rasterizer. + # 如果提供了预先计算的3D协方差矩阵,则使用它。否则,它将由光栅化器根据尺度和旋转进行计算 scales = None rotations = None cov3D_precomp = None @@ -68,21 +77,28 @@ def render(viewpoint_camera, pc : GaussianModel, pipe, bg_color : torch.Tensor, # If precomputed colors are provided, use them. Otherwise, if it is desired to precompute colors # from SHs in Python, do it. If not, then SH -> RGB conversion will be done by rasterizer. + # 如果提供了预先计算的颜色,则使用它们。否则,如果希望在Python中从球谐函数中预计算颜色,请执行此操作。如果没有,则颜色将通过光栅化器进行从球谐函数到RGB的转换 shs = None colors_precomp = None if override_color is None: if pipe.convert_SHs_python: + # 将SH特征的形状调整为(batch_size * num_points,3,(max_sh_degree+1)**2) shs_view = pc.get_features.transpose(1, 2).view(-1, 3, (pc.max_sh_degree+1)**2) + # 计算相机中心到每个点的方向向量,并归一化 dir_pp = (pc.get_xyz - viewpoint_camera.camera_center.repeat(pc.get_features.shape[0], 1)) + # 计算相机中心到每个点的方向向量,并归一化 dir_pp_normalized = dir_pp/dir_pp.norm(dim=1, keepdim=True) + # 使用SH特征将方向向量转换为RGB颜色 sh2rgb = eval_sh(pc.active_sh_degree, shs_view, dir_pp_normalized) + # 将RGB颜色的范围限制在0到1之间 colors_precomp = torch.clamp_min(sh2rgb + 0.5, 0.0) else: shs = pc.get_features else: colors_precomp = override_color - # Rasterize visible Gaussians to image, obtain their radii (on screen). + # Rasterize visible Gaussians to image, obtain their radii (on screen). + # 调用光栅化器,将高斯分布投影到屏幕上,获得渲染图像和每个高斯分布在屏幕上的半径 rendered_image, radii = rasterizer( means3D = means3D, means2D = means2D, diff --git a/train.py b/train.py index 901ca2b..936559c 100644 --- a/train.py +++ b/train.py @@ -34,11 +34,11 @@ except ImportError: def training(dataset, opt, pipe, testing_iterations, saving_iterations, checkpoint_iterations, checkpoint, debug_from): ''' - dataset: 只存储与Moedl相关参数的args - opt: 优化相关参数 - pipe: 管道相关参数 - checkpoint: 已训练模型的路径 - debug_from: 从哪一个迭代开始debug + dataset: 只存储与Moedl相关参数的args + opt: 优化相关参数 + pipe: 管道相关参数 + checkpoint: 已训练模型的路径 + debug_from: 从哪一个迭代开始debug ''' first_iter = 0 # 创建保存结果的文件夹,并保存模型相关的参数到cfg_args文件;尝试创建tensorboard_writer,记录训练过程 @@ -105,7 +105,7 @@ def training(dataset, opt, pipe, testing_iterations, saving_iterations, checkpoi bg = torch.rand((3), device="cuda") if opt.random_background else background # 渲染当前视角的图像 - render_pkg = render(viewpoint_cam, gaussians, pipe, bg) + render_pkg = render(viewpoint_cam, gaussians, pipe, bg, return_depth=True, return_normal=True) image, viewspace_point_tensor, visibility_filter, radii = render_pkg["render"], render_pkg["viewspace_points"], render_pkg["visibility_filter"], render_pkg["radii"] # Loss diff --git a/utils/general_utils.py b/utils/general_utils.py index 37231fe..9d7fc10 100644 --- a/utils/general_utils.py +++ b/utils/general_utils.py @@ -95,8 +95,8 @@ def strip_lowerdiag(L): def strip_symmetric(sym): """ 提取协方差矩阵的对称部分 - :param sym: 协方差矩阵 - :return: 对称部分 + sym: 协方差矩阵 + return: 对称部分 """ return strip_lowerdiag(sym) @@ -129,10 +129,9 @@ def build_rotation(r): def build_scaling_rotation(s, r): """ 构建3D高斯模型的尺度-旋转矩阵 - - :param s: 尺度参数 - :param r: 旋转参数 - :return: 尺度-旋转矩阵 + s: 尺度参数 + r: 旋转参数 + return: 尺度-旋转矩阵 """ L = torch.zeros((s.shape[0], 3, 3), dtype=torch.float, device="cuda") # 初始化尺度矩阵 R = build_rotation(r) # 四元数 -> 旋转矩阵