想象一下,你面前放着一盒晶莹剔透的软糖豆——红的、蓝的、半透明的,它们有的胖嘟嘟,有的扁扁的,有的亮闪闪,有的几乎看不见。你突发奇想:能不能用这些糖豆,堆出一只顾客点的芒果?于是你开始摆弄:把糖豆一颗颗挪位置、捏形状、调颜色、改透明度,从正面看像芒果,再转到侧面看……咦,还得再调调。折腾了千百次之后,你从任何角度望过去,都分不清那是糖豆堆还是真芒果了。 这就是3D高斯泼溅(3D Gaussian Splatting)的灵魂玩法。它不学什么神秘公式来“猜”像素,而是直接把几百万个三维糖豆(3D高斯椭球)撒在场景里,让它们各自带着位置、大小、颜色和透明度,再从任意角度拍一张“糖豆合影”,与真实照片比对后不断微调。这套思路让它比传统神经渲染方法快了几十倍,训练结束就能在游戏显卡上实时漫游。本文带你从“摆糖豆”到“写代码”,把这项技术拆得明明白白。

岗位关联

对AI从业者而言,3DGS是当前3D重建与实时渲染方向落地最快的技术之一,理解它的表示与优化逻辑,能帮你从概念验证走向产品级场景重建。

目录
  1. 可视化演示
  2. 糖豆表示
  3. 投影光栅
  4. 叠影成画
  5. 照图调糖
  6. 密度调控
  7. 性能进化
  8. 工程落地
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

本节配有交互动效(进入视口后自动加载,约 3KB)。

3D\u9ad8\u65af\u6a2a\u7403\u5806\u53e0: \u573a\u666f\u7684\u663e\u5f0f\u8868\u793a \u534f\u65b9\u5dee\u77e9\u9635 \u03a3 = R \u00b7 S \u00b7 S^T \u00b7 R^T \u51b3\u5b9a\u9ad8\u65af\u5f62\u72b6

糖豆表示

先看那盒糖豆。你挑出一颗蓝色软糖,它占据的空间可不是一个点,而是一小团“模糊的区域”——中心最实,边缘渐淡。数学上这种“软乎乎的糖”就叫高斯分布。3D高斯泼溅就是把整个场景当成一个巨大的糖豆拼贴:每一颗糖豆是一个三维高斯椭球,它有胖瘦长短(协方差矩阵)、有中心位置(均值)、有颜色和不透明度。你站远看,无数糖豆叠在一起就糊成了芒果;凑近看,每颗糖豆的边缘都是渐隐的,所以拼缝不明显。

\[

G(\boldsymbol{x}) = \frac{1}{(2\pi)^{3/2}|\boldsymbol{\Sigma}|^{1/2}} \exp\left(-\frac{1}{2}(\boldsymbol{x}-\boldsymbol{\mu})^\top \boldsymbol{\Sigma}^{-1} (\boldsymbol{x}-\boldsymbol{\mu})\right)

\]

1. 均值向量:\(\boldsymbol{x}-\boldsymbol{\mu}\)——“你站的位置离糖豆中心有多远”,离得越远味道越淡。

μ=(μx,μy,μz)\boldsymbol{\mu} = (\mu_x, \mu_y, \mu_z)

2. 协方差矩阵:\(\boldsymbol{\Sigma}\)——它是糖豆的“身材档案”,对角线记录三个方向的胖瘦,非对角项记录它歪着身子还是站着。

Σ=RSS⊤R⊤\boldsymbol{\Sigma} = \boldsymbol{R}\boldsymbol{S}\boldsymbol{S}^\top\boldsymbol{R}^\top

3. 指数衰减:\(\exp(-\frac{1}{2}\ldots)\)——“越远越淡”的自然衰减曲线,保证糖豆没有生硬的边界,叠起来才自然。

e−12d2e^{-\frac{1}{2}d^2}

所以优化糖豆时,真正要调的“旋钮”就这几样:位置\(\boldsymbol{\mu}\)、旋转矩阵\(\boldsymbol{R}\)、缩放对角\(\boldsymbol{S}\)、不透明度\(\alpha\)以及颜色。它们全是从训练照片里自动学出来的——糖豆们自己会摆姿势,不用你一颗颗手捏。

投影光栅

糖豆在三维空间摆好了,可相机拍到的是一张平面照片。每颗胖糖豆投向底片,会变成一个扁扁的椭圆影子。怎么算这个影子?高斯形状有一个妙处:高斯在相机针孔模型下的透视投影,近似还是高斯,只不过中心挪了、胖瘦变了。这个“从3D糖豆到2D椭圆影”的变换,就靠观察矩阵\(W\)和雅可比矩阵\(J\)配合完成。

\[

\boldsymbol{\Sigma}' = \boldsymbol{J}\boldsymbol{W}\boldsymbol{\Sigma}\boldsymbol{W}^\top\boldsymbol{J}^\top

\]

1. 观察变换:乘以\(\boldsymbol{W}\)——把糖豆从世界坐标系搬到相机坐标系,相当于“走到相机跟前,转头看糖豆”。

WΣW⊤\boldsymbol{W}\boldsymbol{\Sigma}\boldsymbol{W}^\top

2. 透视线性化:\(\boldsymbol{J}\)是雅可比矩阵——针孔投影本来会扭曲形状,但靠近投影中心的小范围里,扭曲近似成线性缩放,\(J\)记录了这个缩放的斜率。

J=∂u∂x\boldsymbol{J} = \frac{\partial \boldsymbol{u}}{\partial \boldsymbol{x}}

3. 两段拼接:\(\boldsymbol{\Sigma}'\)——先观察变换、再透视缩放,最终得到屏幕上的2D椭圆糖影,画像素时直接用。

Σ′=J(WΣW⊤)J⊤\boldsymbol{\Sigma}' = \boldsymbol{J}(\boldsymbol{W}\boldsymbol{\Sigma}\boldsymbol{W}^\top)\boldsymbol{J}^\top

传统光栅化要一个三角形一个三角形地画,而3DGS是“按糖豆画椭圆”。因为高斯天然是软的,椭圆边缘自动渐隐,拼出来的画面没有锯齿马赛克感。这就是它敢叫“泼溅”(splatting)的原因——像把颜料甩到画布上,甩出来的不是墨点,是柔和的色斑。

叠影成画

几百个椭圆影子同时落在同一块底片上,怎么办?按“谁离相机近谁先画”的顺序叠起来。这就是画家们说的“近大远小遮挡”:近处的糖豆不透明,就把后面的糖豆遮住了;半透明的糖豆呢,就让它透一点后面的颜色。这个叠加过程有专门的公式——alpha合成。

\[

C = \sum_{i=1}^{n} c_i \alpha_i \prod_{j=1}^{i-1}(1-\alpha_j)

\]

1. 深度排序:下标\(i\)从近到远排——像排队插花,先来的先插入画面。

i=1,2,…,ni = 1, 2, \ldots, n

2. 权重计算:\(\alpha_i\)是第\(i\)颗糖豆的不透明度,\(\prod_{j=1}^{i-1}(1-\alpha_j)\)是它前面所有糖豆透光率的乘积——前面遮得越多,后面露出来的机会越小。

wi=αi∏j=1i−1(1−αj)w_i = \alpha_i \prod_{j=1}^{i-1}(1-\alpha_j)

3. 累加求和:\(\sum c_i w_i\)——每颗糖豆贡献的颜色加权求和,得到最终像素色。

C=∑i=1nwiciC = \sum_{i=1}^{n} w_i c_i

这个公式就是让糖豆拼贴画能“以假乱真”的关键工艺。它全程可微——意思是如果发现某个像素颜色不对,能反向算出是哪颗糖豆的哪个参数该背锅。传统光栅化做不到这么漂亮的可微性,这正是3DGS能一边画一边学的高明之处。

照图调糖

糖豆摆好了,画面渲染出来了,但和真实照片一比,还是差那么点意思:颜色偏了、边缘糊了、某一撮糖豆太密了。于是进入整个流程最核心的环节:拿着照片当标尺,给糖豆打分。分数越低说明拼得越像。3DGS的训练损失由两部分构成:L1损失管整体颜色接近度,D-SSIM损失管局部结构相似度,两者按比例混合。

\[

\mathcal{L} = (1-\lambda)\mathcal{L}_1 + \lambda \mathcal{L}_{\text{D-SSIM}}

\]

1. 像素差:\(\mathcal{L}_1 = \frac{1}{N}\sum |I_{render} - I_{photo}|\)——渲染图与照片每个像素的绝对差值平均,数值越小颜色越接近。

L1=1N∑p∣I^p−Ip∣\mathcal{L}_1 = \frac{1}{N}\sum_{p}|\hat{I}_p - I_p|

2. 结构损失:\(\mathcal{L}_{\text{D-SSIM}} = 1 - \text{SSIM}(\hat{I}, I)\)——SSIM衡量两张图的亮度、对比度、结构三个维度的相似度,值越接近1越好,所以用它补足L1看不到的“纹理质感”。

LD-SSIM=1−SSIM(I^,I)\mathcal{L}_{\text{D-SSIM}} = 1 - \text{SSIM}(\hat{I}, I)

3. 混合系数:\(\lambda\)(通常取0.2)——给“卖相”分配两成注意力,给“口味”分八成,两者合起来才是最终优化目标。

L=0.8L1+0.2LD-SSIM\mathcal{L} = 0.8\mathcal{L}_1 + 0.2\mathcal{L}_{\text{D-SSIM}}

有了损失函数,接下来就是梯度下降的活:把损失对每个糖豆的位置、旋转、缩放、颜色、透明度求导,让它们各自往“让损失变小”的方向挪一小步。每迭代一轮,糖豆们就更贴近真实照片一点。一轮、两轮……几千轮之后,拼贴画和照片几乎看不出差别。这整个过程叫“自适应优化”——糖豆自己会调整,你只负责摆好相机、拍好照片。

密度调控

训练中最妙的部分来了:糖豆的数量不是一开始就定死的。你可能会想,干脆一开始就撒几百万颗糖豆?不行,那样训练慢、显存爆,而且很多地方根本不需要那么多糖。3DGS的做法是让糖豆自己“繁殖”和“淘汰”——这就叫自适应密度控制。

\[

\text{if } \nabla_{\boldsymbol{\mu}}\mathcal{L} \text{ 大 and } \boldsymbol{\Sigma} \text{ 大} \Rightarrow \text{拆分}; \quad \text{if } \nabla_{\boldsymbol{\mu}}\mathcal{L} \text{ 大 and } \boldsymbol{\Sigma} \text{ 小} \Rightarrow \text{克隆}

\]

1. 梯度信号:\(\nabla_{\boldsymbol{\mu}}\mathcal{L}\)——这只手推得用力,说明这颗糖豆的位置严重不对,需要“纠正兵力部署”。

∇μL=∂L∂μ\nabla_{\boldsymbol{\mu}}\mathcal{L} = \frac{\partial \mathcal{L}}{\partial \boldsymbol{\mu}}

2. 拆分:糖豆太大且位置不对时,把它沿最长轴一分为二,两颗小糖豆的子代数由原协方差决定——大块头拆成小块头,覆盖更精细。

Σ1,Σ2←split(Σ)\boldsymbol{\Sigma}_1, \boldsymbol{\Sigma}_2 \leftarrow \text{split}(\boldsymbol{\Sigma})

3. 克隆:糖豆太小但位置不对时,复制一颗挪到附近的偏移位置,让局部“兵力”更密集。

μ2=μ1+ϵ\boldsymbol{\mu}_2 = \boldsymbol{\mu}_1 + \epsilon

同时,每隔一定步数会检查所有糖豆的不透明度:如果哪颗糖豆透明得像空气(\(\alpha\)趋近0),说明它对画面毫无贡献还白占显存,直接删除。这套“繁殖-淘汰”机制让糖豆数量在训练过程中自动膨胀到几十万到几百万颗,哪里细节多就哪里密集,哪里一片空就哪里稀疏——最终得到的是一个精准分配算力的糖豆军团。

性能进化

为什么3DGS能比NeRF快几十倍?打个比方:NeRF像一名画家,画每个像素前都要跑进房间深处翻找“这个点应该是什么颜色”的配方表(多层感知机MLP),沿途还要反复采样几十上百次光线位置,每次都得重新算一遍;3DGS干脆把糖豆直接摆好,画每个像素时只需问一句“哪些豆子投到了这里?”然后快速按深度叠一下就行。

\[

\text{NeRF: } C(\boldsymbol{r}) = \int_{t_n}^{t_f} T(t)\sigma(\boldsymbol{r}(t))c(\boldsymbol{r}(t),\boldsymbol{d})dt \quad \text{vs} \quad \text{3DGS: } C = \sum_i c_i \alpha_i \prod_{j<i}(1-\alpha_j)

\]

1. NeRF的积分:\(\int\)——光线路径上每个点都要查一遍密度\(\sigma\)和颜色\(c\),然后积分加总,像沿路跑遍每个驿站收信。

C(r)=∫tntfT(t)σ(t)c(t)dtC(\boldsymbol{r}) = \int_{t_n}^{t_f} T(t)\sigma(t)c(t)dt

2. 3DGS的求和:\(\sum\)——只有糖影覆盖到这个像素的糖豆参与计算,每个像素覆盖的糖豆数量通常只有几十颗,算起来自然是闪电速度。

C=∑i∈pixelciαiTiC = \sum_{i \in \text{pixel}} c_i \alpha_i T_i

3. 显式vs隐式:NeRF把场景“记”在神经网络权重里,要经过网络前向推理才能读取;3DGS的糖豆参数是裸数据,GPU直接读取光栅化,天然为实时渲染而生。

重量级≈推理开销大,轻量级≈直接查表\text{重量级} \approx \text{推理开销大}, \quad \text{轻量级} \approx \text{直接查表}

得益于这种“显式糖豆+光栅化”的组合,3DGS在训练完后的渲染速度能达到100fps以上,足以在消费级显卡上自由漫游。这也让它成为数字孪生、VR/AR、影视特效等需要实时交互场景的首选技术——不再像NeRF那样只适合离线出图。

工程落地

糖豆世界的理论很美好,真正动手训练一锅3DGS需要什么?先得拍好照片。绕着一个物体或走进一个房间,拍几十到几百张照片,保证每两个相邻视角之间重叠度足够。然后用COLMAP做“相机标定”——相当于给你的糖豆士兵们划定精确的编制:每张照片是在哪个位置、朝哪个方向拍的。姿势错误会直接导致训练崩塌,就像糖豆被要求摆出“不可能的姿势”。

\[

\text{COLMAP: } \{R_i, t_i, K\}_{i=1}^N = \arg\min \sum_{i,j} \| \pi(K, R_i, t_i, X_j) - u_{ij} \|^2

\]

1. 相机位姿:\(R_i, t_i\)——第\(i\)张照片的旋转和位移,就是相机在空间里站在哪、往哪看。

Pi=[Ri∣ti]P_i = [R_i \mid t_i]

2. 内参矩阵:\(K\)——镜头自身的焦距和畸变,告诉你这张照片是广角还是长焦拍的。

K=[fx0cx0fycy001]K = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}

3. 投影与误差:\(\pi(K, R_i, t_i, X_j)\)——把3D点投影到2D图像坐标,与实际检测特征点\(u_{ij}\)差得越小,标定越准。

π(⋅)=(x′z′,y′z′)\pi(\cdot) = \left(\frac{x'}{z'}, \frac{y'}{z'}\right)

拿到标定数据之后,初始化一片稀疏的高斯点云,然后进入“照图调糖”训练流程。最佳实践是:先用官方代码库在单个GPU上训练数十分钟到数小时(视场景规模而定),期间密切观察损失曲线和可视化中间渲染结果;导出时采用splat格式或转换为PLY点云格式供不同端侧使用。显存不够时减少初始点数、降低图像分辨率,或用分块训练策略。等你熟练了,会发现这套流程像做菜——COLMAP是备菜,训练是炒菜,导出装盘,火候和配料比例都在实践中慢慢掌握。

AI 应用场景

电商与文物保护的三维重建

阶段:数据采集与训练推理

解决的问题:传统3D建模靠艺术家手工雕刻,一个文物或商品建摸耗时要数天到数周,成本高且容易出现失真。3DGS只需围绕物体拍摄百余张照片,训练几十分钟就能得到一个可360°查看的照片级3D模型,而且模型可以嵌入网页实时交互。

具体案例:某博物馆与科技公司合作,用手机拍摄一尊青铜器约200张照片,用3DGS训练出三维模型后部署到官网虚拟展厅,观众可在浏览器中旋转放大查看每一处纹路和锈迹,加载速度秒开。

自动驾驶与机器人的场景仿真

阶段:数据生成与闭环测试

解决的问题:自动驾驶路测成本高昂且难以覆盖极端场景。用3DGS重建真实街道的3D场景后,可以生成任意新视角图像,为感知模型提供海量带标注的训练数据,也能在仿真环境中反复测试安全策略。

具体案例:一家自动驾驶公司采集了某城区路口的环视视频,建出高斯场景后,在仿真器中模拟不同天气、光照和遮挡条件下的相机视角,让视觉模型学会在更低可见度下不丢目标。

影视虚拟制片

阶段:现场实拍与后期合成

解决的问题:传统绿幕拍摄需要大量后期抠像、补光,演员的站位也受限。3DGS可以实时重建演员身边的场景,然后在引擎中任意改变机位,让虚拟镜头穿行于真实布景之间,获得沉浸式动态运镜体验。

具体案例:某综艺节目用多台固定相机捕捉舞台全景,训练出3D场景后制作“子弹时间”式环绕镜头,导演可以在计算机上自由拉近推远,制作效率提升数倍。

Python 演示

python50 行
import numpy as np class GaussianField:    def __init__(self, count=128):        self._pos = np.random.rand(count, 2).astype(np.float32) * 1.0        self._scale = np.random.rand(count, 2).astype(np.float32) * 0.08 + 0.01        self._color = np.random.rand(count, 3).astype(np.float32) * 0.5 + 0.25        self._alpha = np.full(count, 0.3, dtype=np.float32)     def render(self, height=32, width=32):        ys, xs = np.mgrid[0:height, 0:width].astype(np.float32) / max(height, width)        out = np.zeros((height, width, 3), dtype=np.float32)        for i in range(len(self._pos)):            dx = xs - self._pos[i, 0]            dy = ys - self._pos[i, 1]            weight = np.exp(-0.5 * ((dx / max(self._scale[i, 0], 1e-3)) ** 2 +                                    (dy / max(self._scale[i, 1], 1e-3)) ** 2))            alpha = self._alpha[i] * weight            out = out * (1 - alpha[..., None]) + self._color[i] * alpha[..., None]        return np.clip(out, 0, 1)     def train(self, target, epochs=300, lr=0.05):        for epoch in range(epochs):            rendered = self.render(*target.shape[:2])            loss = float(np.mean((rendered - target) ** 2))            grad_img = 2 * (rendered - target) / target.size            for i in range(len(self._pos)):                dx = xs - self._pos[i, 0]                dy = ys - self._pos[i, 1]                weight = np.exp(-0.5 * ((dx / max(self._scale[i, 0], 1e-3)) ** 2 +                                        (dy / max(self._scale[i, 1], 1e-3)) ** 2))                alpha = self._alpha[i] * weight                g = grad_img * (self._color[i] - out_prev) * alpha[..., None]                self._pos[i, 0] -= lr * float(np.sum(g[..., 0] * dx * weight))                self._pos[i, 1] -= lr * float(np.sum(g[..., 1] * dy * weight))                self._color[i] -= lr * float(np.sum(grad_img * alpha[..., None]))                self._alpha[i] -= lr * float(np.sum(grad_img * weight[..., None]))            if epoch % 30 == 0:                print("epoch", epoch, "loss", round(loss, 6)) if __name__ == "__main__":    target = np.zeros((32, 32, 3), dtype=np.float32)    ys, xs = np.mgrid[0:32, 0:32].astype(np.float32)    mask = ((xs - 16) ** 2 + (ys - 16) ** 2) < 64    target[mask] = [1.0, 0.6, 0.2]    ys, xs = np.mgrid[0:32, 0:32].astype(np.float32)    field = GaussianField(count=64)    field.train(target, epochs=300, lr=0.05)    final = field.render(32, 32)    print("final mse", round(float(np.mean((final - target) ** 2)), 6))
目的:用纯NumPy实现一个2D版本的“高斯泼溅”——上百颗糖豆(2D高斯)通过alpha合成拼出目标图案,手动实现梯度下降微调糖豆参数。
  1. self._pos = np.random.rand(count, 2)初始化每颗糖豆的位置,随机撒在画布上。
  2. weight = np.exp(-0.5 * ((dx / scale_x)**2 + (dy / scale_y)**2))计算每个像素离糖豆中心的“糖浓度”,越近越浓。
  3. out = out * (1 - alpha[..., None]) + self._color[i] * alpha[..., None]这就是alpha合成公式,把新糖影叠到已有画面上。
  4. grad_img = 2 * (rendered - target) / target.size求渲染图和目标图的误差梯度,指导糖豆往哪儿挪。
  5. self._pos[i, 0] -= lr * ...按梯度方向微调这颗糖豆的位置、颜色和透明度。

常见误区

误区我听说3DGS比NeRF快几十倍,那它一定是在NeRF的网络结构上做了优化吧?本质还是神经网络隐式表示。

正解3DGS和NeRF是两条技术路线。NeRF把场景藏在MLP的权重里,查询时逐点推理;3DGS把场景显式表示为几百万颗高斯椭球参数,用可微光栅化直接画出来。显式表示让GPU能像传统图形学那样并行光栅化,这才是速度差异的根源。

为何常见:因为3DGS常被归类到“神经渲染”大旗之下,大家很自然地把它当成NeRF家族的后继者,忽视了表示方式的根本切换。

误区训练时把高斯数量加到一千万颗,细节肯定多,画面肯定会更清晰。

正解高斯数量只是表达能力的一个维度。过密的高斯会互相重叠,不仅显存爆炸,还会引入噪声和过拟合;真正的关键是“自适应密度控制”——把糖豆分配到梯度信号的区域,动态调整,而不是盲目堆数量。

为何常见:深度学习中“模型越大越好”的直觉被迁移过来,但3DGS是显式几何,数量需要与场景复杂度匹配,不能一刀切。

误区能重建出照片级场景的高科技,训练一定得上GPU服务器集群。

正解3DGS的优化只涉及少量参数和光栅化操作,单个消费级GPU(如RTX 3090)就能训练中等规模的场景,几十万颗高斯通常在半小时到几小时内收敛,比NeRF的几天训练量级轻得多。

为何常见:看到论文里动辄几百张照片和千万级参数,就下意识认为硬件门槛极高,忽略了显式表示和光栅化的计算效率。

误区我手机摄像头才几千万像素,肯定不如单反拍出来的场景重建质量高。

正解3DGS的关键在于视角覆盖和相机位姿准确性,而不是单张照片的分辨率。几十张手机照片只要视角重叠充分、COLMAP标定准确,同样能重建出干净的场景;相机位姿错了,再好的镜头也会崩。

为何常见:人们习惯用“像素高低”推断一切画质问题,忽略了3D重建中对运动恢复结构(SfM)精度的核心依赖。

面试题

Q1. 3D高斯泼溅中,每一颗三维高斯糖豆主要携带哪些参数?

单选题 · easy

  • A.位置、协方差矩阵、颜色和不透明度← 正确答案
  • B.仅位置和虚拟深度数值
  • C.仅颜色和透明度两个通道
  • D.深度法线、材质贴图和UV坐标

答案:A。一颗3D高斯需要用均值(位置)确定中心,协方差矩阵确定胖瘦朝向,颜色和球谐系数确定视觉外貌,不透明度确定遮挡属性。B、C、D都缺少关键几何参数,无法描述一颗糖豆在三维空间中的分布。

Q2. 与NeRF相比,3DGS渲染速度快几十倍的根本原因是什么?

单选题 · easy

  • A.它使用了更大规模的神经网络
  • B.场景为显式高斯表示,渲染走光栅化而非逐点查询← 正确答案
  • C.训练时跳过了相机标定步骤
  • D.GPU显存使用的是专用高速专用通道

答案:B。NeRF渲染每条光线要沿路径采样几十上百个点并查MLP,属于隐式逐个点推理;3DGS把场景显式存储为高斯参数,能像传统光栅化一样并行绘制椭圆。B描述了这个本质区别,其他选项与光栅化加速无关。

Q3. 下列哪项属于3DGS中自适应密度控制的典型操作?

单选题 · easy

  • A.每轮训练后把所有高斯缩小一半
  • B.大且梯度大的高斯拆分,小且梯度大的高斯克隆← 正确答案
  • C.随机删除一半不透明度为零的高斯
  • D.将场景高斯数量写入模型配置文件固定不变

答案:B。自适应密度控制(ADC)根据梯度信号和形状决定拆分或克隆:大而错拆两半,小而缺克隆补充,另外剪枝透明高斯。B最准确,A和D没在控制,C只覆盖了剪枝的一部分,不是完整做法。

Q4. 3DGS训练时的总损失函数通常包含哪两部分?

单选题 · mid

  • A.交叉熵损失与L2正则化
  • B.L1像素差损失与D-SSIM结构损失← 正确答案
  • C.感知损失与对抗生成损失
  • D.深度误差与光流一致性损失

答案:B。3DGS用 \((1-\lambda)\mathcal{L}_1 + \lambda\mathcal{L}_{\text{D-SSIM}}\) 作为监督信号,L1管逐像素颜色贴近采样,D-SSIM管局部亮度、对比度、结构。A是分类任务常用,C、D多见于生成或视频类模型,不是3DGS主体损失。

Q5. 高斯投影到2D图像的协方差计算公式是下列哪一项?

单选题 · mid

  • A.\(\Sigma' = J W \Sigma W^T J^T\)← 正确答案
  • B.\(\Sigma' = \Sigma W J\)
  • C.\(\Sigma' = J^T W^T \Sigma W J\)
  • D.\(\Sigma' = W \Sigma J\)

答案:A。先做观察变换 \(W\Sigma W^T\),将3D协方差转到相机坐标系,再乘雅可比 \(J\) 描述透视线性化,最终得到2D高斯投影 \(J(W\Sigma W^T)J^T\)。其他选项矩阵乘序错误,不具备变换语义。

Q6. 训练3DGS之前,为什么通常先用COLMAP处理照片集?

单选题 · mid

  • A.为了给照片统一加滤镜
  • B.为了计算每张照片对应的相机位姿和稀疏点云← 正确答案
  • C.为了把照片压缩成网络权重
  • D.为了给高斯糖豆分配独立图形学贴图

答案:B。3DGS需要把糖豆锚定在三维空间,而照片本身没有三维坐标。COLMAP通过特征点匹配和三角化估计相机位姿 \((R,t)\) 与三维点云,这些信息是高斯初始化与训练的先决条件,相当于给糖豆画好“户型图”。

Q7. 下面哪些属于3DGS中一个高斯糖豆的可优化参数?

多选题 · mid

  • A.位置均值向量← 正确答案
  • B.旋转矩阵和缩放向量← 正确答案
  • C.球的切面阴影强度
  • D.不透明度与球谐颜色系数← 正确答案

答案:ABD。可优化参数包括均值(位置)、协方差分解出的旋转\(R\)和缩放\(S\)、不透明度\(\alpha\)、颜色及球谐系数。切面阴影属于传统光照模型概念,3DGS用球谐表示视差颜色,不显式定义切面阴影。

Q8. 在3DGS中,“拆分”和“克隆”两种自适应操作的区别是什么?

多选题 · hard

  • A.拆分适用于高斯过大的情况,一分为二← 正确答案
  • B.克隆适用于高斯过小但覆盖不足的情况← 正确答案
  • C.拆分和克隆都会保留原来的高斯个体
  • D.克隆会删除原本不透明度较高的原高斯

答案:AB。大高斯在梯度强烈时被沿长轴拆分,小高斯在位置不足时被克隆并推往邻近偏移点;两种操作都让局部表现力增强。C对拆分来说不成立,因为拆分替代并删除了原高斯;D把克隆说成删除语义也不对。

Q9. 关于3DGS与NeRF两种技术的差异,下列说法正确的有哪些?

多选题 · hard

  • A.3DGS场景表示为显式高斯集合← 正确答案
  • B.NeRF渲染需要对光线逐点连续采样← 正确答案
  • C.3DGS渲染必须使用专用的光线追踪硬件
  • D.3DGS可微光栅化支持梯度回传与优化← 正确答案

答案:ABD。3DGS是显式表示,NeRF是隐式MLP加体渲染积分;3DGS自定义的可微光栅化让损失梯度能流回高斯参数。C是错误选项,3DGS不需要光追硬件,普通光栅化管线就能跑。

Q10. 一颗半透明的糖豆(不透明度 \(\alpha=0.5\))位于最前方,糖豆后面紧挨着一堵纯蓝色背景墙,最终像素颜色是什么?

单选题 · extreme

  • A.全由红色决定,背景被完全遮挡
  • B.红色占一半权重、蓝色占一半权重← 正确答案
  • C.蓝色完全不参与颜色叠加
  • D.叠加结果取决于相机焦距大小

答案:B。按alpha合成公式 \(C = c_{\text{front}} \alpha + c_{\text{back}}(1-\alpha)\),代入 \(\alpha=0.5\) 得红色一半+蓝色一半。A假设完全不透明,C假设完全透明,D与焦距无关,故选B。