编辑
2024-04-24
NeRF
00
请注意,本文编写于 181 天前,最后修改于 181 天前,其中某些信息可能已经过时。

目录

alpha-blending
computeColorFromSH
semantic from gaussian?
other information from gaussian?

alpha-blending

下面是一段3dgs的原文

Specifically, the color CC is given by volumetric rendering along a ray:

C=i=1NTi(1exp(σiδi))ciwithTi=exp(j=1i1σjδj)\begin{equation}C=\sum_{i=1}^NT_i(1-\exp(-\sigma_i\delta_i))\mathbf{c}_i\quad\mathrm{with}\quad T_i=\exp\left(-\sum_{j=1}^{i-1}\sigma_j\delta_j\right) \end{equation}

where samples of density σ\sigma, transmittance TT, and color cc are taken along the ray with intervals δi\delta_i. This can be re-written as

C=i=1NTiαici,\begin{equation}C=\sum_{i=1}^NT_i\alpha_i\mathbf{c}_i,\end{equation}

with

αi=(1exp(σiδi)) and Ti=j=1i1(1αi).\alpha_i=(1-\exp(-\sigma_i\delta_i))\mathrm{~and~}T_i=\prod_{j=1}^{i-1}(1-\alpha_i).

这是标准nerf的渲染方程,注意(2)(2)式的形式,这里TT表示为透射率,α\alpha是一个与采样间隔、体密度有关的值,cc是点ii处的颜色。

根据Volume Rendering Digest这篇文章中的推导

由于将σ\sigma视作表示射线击中粒子的微分可能性(即在行驶无穷小距离时击中粒子的概率)。解出微分方程的形式中就会带有exp\exp{}项,排除掉这些数学符号的干扰,其本质是一种alpha-blending或者叫 alpha compositing

那么对于3dgs来说,其alpha-blending的形式,

C=iNciαij=1i1(1αj),\begin{equation}C=\sum_{i\in N}c_i\alpha_i\prod_{j=1}^{i-1}(1-\alpha_j),\end{equation}

也就很好理解了。

其中cic_i是该splatting在渲染方向上的颜色,αi\alpha_i是一个学习到的透明度值。

computeColorFromSH

其中cic_i是与方向有关的颜色值,本质上是一组球谐函数的基,在3dgs的cuda源码中可以找到

cpp
// Forward method for converting the input spherical harmonics // coefficients of each Gaussian to a simple RGB color. __device__ glm::vec3 computeColorFromSH(int idx, int deg, int max_coeffs, const glm::vec3* means, glm::vec3 campos, const float* shs, bool* clamped) { // The implementation is loosely based on code for // "Differentiable Point-Based Radiance Fields for // Efficient View Synthesis" by Zhang et al. (2022) glm::vec3 pos = means[idx]; glm::vec3 dir = pos - campos; dir = dir / glm::length(dir); glm::vec3* sh = ((glm::vec3*)shs) + idx * max_coeffs; glm::vec3 result = SH_C0 * sh[0]; if (deg > 0) { float x = dir.x; float y = dir.y; float z = dir.z; result = result - SH_C1 * y * sh[1] + SH_C1 * z * sh[2] - SH_C1 * x * sh[3]; if (deg > 1) { float xx = x * x, yy = y * y, zz = z * z; float xy = x * y, yz = y * z, xz = x * z; result = result + SH_C2[0] * xy * sh[4] + SH_C2[1] * yz * sh[5] + SH_C2[2] * (2.0f * zz - xx - yy) * sh[6] + SH_C2[3] * xz * sh[7] + SH_C2[4] * (xx - yy) * sh[8]; if (deg > 2) { result = result + SH_C3[0] * y * (3.0f * xx - yy) * sh[9] + SH_C3[1] * xy * z * sh[10] + SH_C3[2] * y * (4.0f * zz - xx - yy) * sh[11] + SH_C3[3] * z * (2.0f * zz - 3.0f * xx - 3.0f * yy) * sh[12] + SH_C3[4] * x * (4.0f * zz - xx - yy) * sh[13] + SH_C3[5] * z * (xx - yy) * sh[14] + SH_C3[6] * x * (xx - 3.0f * yy) * sh[15]; } } } result += 0.5f; // RGB colors are clamped to positive values. If values are // clamped, we need to keep track of this for the backward pass. clamped[3 * idx + 0] = (result.x < 0); clamped[3 * idx + 1] = (result.y < 0); clamped[3 * idx + 2] = (result.z < 0); return glm::max(result, 0.0f); }

这段代码用gpt解释

txt
这段代码是一个CUDA内核函数,用于将球谐系数(spherical harmonics coefficients)转换为简单的RGB颜色。这个函数是图形渲染中的一部分,特别是在计算光源对场景中物体颜色的影响时。球谐函数是拉普拉斯方程在球坐标系中的解,它们在描述光的散射和辐射传输中非常有用。 下面是对这段代码的逐行解释: __device__ 关键字表明这个函数可以在GPU上作为CUDA内核运行。 glm::vec3 computeColorFromSH(...) 定义了一个函数,它接受球谐系数、球面谐波的阶数、最大系数数、高斯分布的均值、相机位置、球谐系数数组和是否被截断的标志数组作为输入,并返回一个glm::vec3类型的RGB颜色。 glm::vec3 pos = means[idx]; 获取当前高斯分布的均值位置。 glm::vec3 dir = pos - campos; 计算从相机位置到当前位置的方向向量。 dir = dir / glm::length(dir); 归一化方向向量。 glm::vec3* sh = ((glm::vec3*)shs) + idx * max_coeffs; 计算指向当前高斯分布球谐系数数组的指针。 glm::vec3 result = SH_C0 * sh[0]; 初始化结果颜色,使用阶数为0的球谐系数。 if (deg > 0) 开始一个条件块,用于计算阶数大于0的球谐系数对颜色的影响。 9-15. 在这个条件块内部,计算更高阶的球谐系数对颜色的贡献。SH_C1, SH_C2, SH_C3 应该是预定义的系数数组,用于计算不同阶数的球谐系数对最终颜色的影响。 result += 0.5f; 将一个小的偏移量加到结果颜色上,以避免颜色太暗。 17-19. clamped 数组用于跟踪RGB颜色分量是否被截断(即是否小于0)。如果某个分量小于0,相应的标志会被设置为true。 return glm::max(result, 0.0f); 确保所有颜色分量都是非负的,返回最终的RGB颜色。 这个函数的目的是将复杂的球谐分析转换为直观的RGB颜色,这在光线追踪和实时渲染算法中很常见。代码中提到的“Differentiable Point-Based Radiance Fields for Efficient View Synthesis”由Zhang等人在2022年提出,这是一种先进的视图合成技术,它允许在保持渲染效率的同时,对场景进行不同的光照和视角变化。

3dgs默认使用了3阶的球谐函数。

semantic from gaussian?

于是我们会思考一个问题,我们可以使用3dgs渲染一个语义图么?

理论上也是可以的,只需要把(3)(3)式中的cc改成ss,让ss也是一组球谐函数的基,然后对应也要有另一组学习到的α\alpha,这样就可以渲染出一张语义图了。但是该如何输入监督信息呢?

我们可以将输入的图像用语义分割网络进行处理,这样每一个view就也带有一张语义图真值了。

思考1:会不会造成语义空间上的不连续?由于仅仅使用2d的监督信息,可能会造成ss只在有语义真值的渲染方向上表现较好,而在没见过的方向上,语义的表现较差,但是实际上语义随渲染方向的改变应该很小。(同一个物体的语义不随方向改变?)

思考2:如何引入3d信息对语义进行修正?在点云语义分割任务上,有很多可以参考的文章。

other information from gaussian?

本文作者:insomnia

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!