3DGS CUDA代码笔记

2024-04-24 11:28
文章标签 代码 笔记 cuda 3dgs

本文主要是介绍3DGS CUDA代码笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本篇文章 一Scaffold GS 为例子。 目标在里面添加 Render Depth 的代码:

将可见的 Gaussians Render 到 2D 图像上面

from diff_gaussian_rasterization import GaussianRasterizationSettings, GaussianRasterizer
.......rasterizer = GaussianRasterizer(raster_settings=raster_settings)
rendered_image, radii = rasterizer(means3D = xyz,             #  高斯的中心点 means2D = screenspace_points,   ##  return 数值shs = None,colors_precomp = color,opacities = opacity,scales = scaling,rotations = rot,cov3D_precomp = None)

上面那个 GuassianRasterizer 是从 diff_gaussian_rasterization 这个 package 中导入进来的、 因此,我找到 diff_gaussian_rasterization 这个文件夹,首先 看其对应的 init.py 这个函数。因为每次 import 这个package 的时候 都会首先执行一次 这个文件夹下面的 init.py 作为包的初始化函数

这个 Init 函数里面 回调用 rasterize_gaussians CUDA 的 函数:

 return rasterize_gaussians(means3D,means2D,shs,colors_precomp,opacities,scales, rotations,cov3D_precomp,raster_settings, )继续调用:
def rasterize_gaussians(means3D,means2D,sh,colors_precomp,opacities,scales,rotations,cov3Ds_precomp,raster_settings,
):return _RasterizeGaussians.apply(means3D,means2D,sh,colors_precomp,opacities,scales,rotations,cov3Ds_precomp,raster_settings,)

最后跳入到 _RasterizeGaussians 的 forward 函数当中

num_rendered, color, radii, geomBuffer, binningBuffer, imgBuffer = _C.rasterize_gaussians(*args)

_C 表示 在当前的 Cpp 文件中去 找这个 rasterize_gaussians 的函数,

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {m.def("rasterize_gaussians", &RasterizeGaussiansCUDA);m.def("rasterize_gaussians_backward", &RasterizeGaussiansBackwardCUDA);m.def("rasterize_aussians_filter", &RasterizeGaussiansfilterCUDA);m.def("mark_visible", &markVisible);}

发现对应的 RasterizeGaussiansCUDA 函数

这个 函数 通过 ext.
cpp
查询可以发现是 rasterize_points.cu 里面的 函数:

下面这个函数主要是定义了 一些需要返回的 变量,启动 核函数

RasterizeGaussiansCUDA(const torch::Tensor& background,const torch::Tensor& means3D,const torch::Tensor& colors,const torch::Tensor& opacity,const torch::Tensor& scales,const torch::Tensor& rotations,const float scale_modifier,const torch::Tensor& cov3D_precomp,const torch::Tensor& viewmatrix,const torch::Tensor& projmatrix,const float tan_fovx, const float tan_fovy,const int image_height,const int image_width,const torch::Tensor& sh,const int degree,const torch::Tensor& campos,const bool prefiltered,const bool debug)
{if (means3D.ndimension() != 2 || means3D.size(1) != 3) {AT_ERROR("means3D must have dimensions (num_points, 3)");}const int P = means3D.size(0);const int H = image_height;const int W = image_width;auto int_opts = means3D.options().dtype(torch::kInt32);auto float_opts = means3D.options().dtype(torch::kFloat32);torch::Tensor out_color = torch::full({NUM_CHANNELS, H, W}, 0.0, float_opts);torch::Tensor radii = torch::full({P}, 0, means3D.options().dtype(torch::kInt32));torch::Device device(torch::kCUDA);torch::TensorOptions options(torch::kByte);torch::Tensor geomBuffer = torch::empty({0}, options.device(device));torch::Tensor binningBuffer = torch::empty({0}, options.device(device));torch::Tensor imgBuffer = torch::empty({0}, options.device(device));std::function<char*(size_t)> geomFunc = resizeFunctional(geomBuffer);std::function<char*(size_t)> binningFunc = resizeFunctional(binningBuffer);std::function<char*(size_t)> imgFunc = resizeFunctional(imgBuffer);int rendered = 0;if(P != 0){int M = 0;if(sh.size(0) != 0){M = sh.size(1);}rendered = CudaRasterizer::Rasterizer::forward(geomFunc,binningFunc,imgFunc,P, degree, M,background.contiguous().data<float>(),W, H,means3D.contiguous().data<float>(),sh.contiguous().data_ptr<float>(),colors.contiguous().data<float>(), opacity.contiguous().data<float>(), scales.contiguous().data_ptr<float>(),scale_modifier,rotations.contiguous().data_ptr<float>(),cov3D_precomp.contiguous().data<float>(), viewmatrix.contiguous().data<float>(), projmatrix.contiguous().data<float>(),campos.contiguous().data<float>(),tan_fovx,tan_fovy,prefiltered,out_color.contiguous().data<float>(),radii.contiguous().data<int>(),debug);}return std::make_tuple(rendered, out_color, radii, geomBuffer, binningBuffer, imgBuffer);
}

之后 进入 CudaRasterizer::Rasterizer::forward 函数,其定义在 rasterizer_impl.cu 对应的文件。 这个 forward 函数 最后会调用 FORWARD 类里面的 render 函数, 真实的 Render 过程是在下面这个函数执行的,我们

CHECK_CUDA(FORWARD::render(tile_grid, block,imgState.ranges,binningState.point_list,width, height,geomState.means2D,feature_ptr,geomState.conic_opacity,imgState.accum_alpha,out_alpha,imgState.n_contrib,background,out_color,out_depth), debug)

最后的 Depth Render 的函数是在 renderCUDA 函数中进行的。
实际修改的代码:

## 定义 CUDA 的变量
float weight = 0;
float D = 0;## 使用深度的加权去 计算真实的depth 的数值
weight += alpha * T;
D += depths[collected_id[j]] * alpha * T;

在 添加的时候,也添加了对于 Depth 的 BP 的操作,但是如果只需要可视化 depth 的话可以不用添加。

参考网址: https://github.com/ashawkey/diff-gaussian-rasterization

这篇关于3DGS CUDA代码笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/931620

相关文章

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

Java 线程池+分布式实现代码

《Java线程池+分布式实现代码》在Java开发中,池通过预先创建并管理一定数量的资源,避免频繁创建和销毁资源带来的性能开销,从而提高系统效率,:本文主要介绍Java线程池+分布式实现代码,需要... 目录1. 线程池1.1 自定义线程池实现1.1.1 线程池核心1.1.2 代码示例1.2 总结流程2. J

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

Vue实现路由守卫的示例代码

《Vue实现路由守卫的示例代码》Vue路由守卫是控制页面导航的钩子函数,主要用于鉴权、数据预加载等场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、概念二、类型三、实战一、概念路由守卫(Navigation Guards)本质上就是 在路

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

JAVA实现Token自动续期机制的示例代码

《JAVA实现Token自动续期机制的示例代码》本文主要介绍了JAVA实现Token自动续期机制的示例代码,通过动态调整会话生命周期平衡安全性与用户体验,解决固定有效期Token带来的风险与不便,感兴... 目录1. 固定有效期Token的内在局限性2. 自动续期机制:兼顾安全与体验的解决方案3. 总结PS

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

Python屏幕抓取和录制的详细代码示例

《Python屏幕抓取和录制的详细代码示例》随着现代计算机性能的提高和网络速度的加快,越来越多的用户需要对他们的屏幕进行录制,:本文主要介绍Python屏幕抓取和录制的相关资料,需要的朋友可以参考... 目录一、常用 python 屏幕抓取库二、pyautogui 截屏示例三、mss 高性能截图四、Pill

使用MapStruct实现Java对象映射的示例代码

《使用MapStruct实现Java对象映射的示例代码》本文主要介绍了使用MapStruct实现Java对象映射的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、什么是 MapStruct?二、实战演练:三步集成 MapStruct第一步:添加 Mave

Java抽象类Abstract Class示例代码详解

《Java抽象类AbstractClass示例代码详解》Java中的抽象类(AbstractClass)是面向对象编程中的重要概念,它通过abstract关键字声明,用于定义一组相关类的公共行为和属... 目录一、抽象类的定义1. 语法格式2. 核心特征二、抽象类的核心用途1. 定义公共接口2. 提供默认实