导读:本期聚焦于巫师创作的《3DGS遮挡剔除怎么做?视锥与遮挡剔除如何协同加速渲染》,敬请观看详情。把几十万个三维高斯抛到屏幕上,GPU很快就会被看不见的点拖垮。视锥剔除先砍掉相机视野外的球,遮挡剔除再删掉被前景挡住的高斯,两者串行能省掉大半光栅化开销。实际工程里常用层次包围盒做粗筛,再用硬件遮挡查询或软件光栅深度图做精判。本文从原理到代码说明怎样在3DGS管线中搭这套机制,并对比不同方案在城市场景下的帧率差异,指出深度图分辨率与更新频率才是瓶颈而非算法本身。

在三维高斯泼溅(3DGS)的实时渲染里,场景往往由数百万个高斯椭圆构成。如果每一帧都把全部高斯送入光栅化阶段,显存带宽和片元着色开销都会爆炸。视锥剔除负责把相机视锥体之外的高斯提前丢弃,遮挡剔除则进一步识别那些落在视锥内却被建筑物、山体等不透明前景完全挡住的高斯。把这两种策略串到一条管线里,渲染负载能下降到原来的三到五成,且视觉结果几乎无差。下面这张示意图展示了一个典型城市场景中经两级剔除后的剩余高斯分布。

3DGS遮挡剔除怎么做?视锥与遮挡剔除如何协同加速渲染

视锥剔除的基础原理与实现

视锥剔除的本质是用相机投影矩阵定义的六个平面去测试每个高斯的包围球。三维高斯在泼溅前可以近似为各向异性椭球,但做粗粒度剔除时通常取其最大轴半径生成包围球,这样能避免复杂的椭球平面相交判断。只要包围球中心到某个平面的有符号距离加上半径小于零,就说明该球完全在该平面背面,从而整个高斯不可能出现在画面中。

在3DGS的排序阶段之前插入视锥剔除最为高效,因为此时高斯仍以结构化数组存放于显存或内存,可以用计算着色器批量处理。下面是一段简化的CUDA风格伪代码,展示如何对高斯中心与半径做平面测试:

struct Plane { float nx, ny, nz, d; };
__global__ void frustum_cull(
    const float* centers, const float* radii,
    const Plane* planes, int* visible_mask, int n) {
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    if (i >= n) return;
    float cx = centers[3*i], cy = centers[3*i+1], cz = centers[3*i+2];
    float r = radii[i];
    int vis = 1;
    for (int p = 0; p < 6; ++p) {
        float dist = planes[p].nx*cx + planes[p].ny*cy + planes[p].nz*cz + planes[p].d;
        if (dist < -r) { vis = 0; break; }
    }
    visible_mask[i] = vis;
}

这种实现的优点是逻辑简单、易于并行,缺点在于包围球过于保守,在长焦或倾斜视角下会保留不少实际不可见的高斯。因此在大型场景中,往往先用八叉树或层次包围盒把空间分块,只对与视锥相交的节点展开内部高斯的精确测试,从而把遍历复杂度从线性降到近似对数级。

遮挡剔除的常用方案与精度权衡

视锥剔除之后,仍有大量高斯位于视野内但被前景挡住。传统多边形渲染常用硬件遮挡查询,但在3DGS里高斯并非三角形,不能直接走图形管线的遮挡谓词。更实用的做法是软件遮挡:把上一帧或低分辨率深度预渲染的结果存为深度图,再用每个高斯的屏幕空间包围圆去比深度。若包围圆内所有采样点的深度均大于深度图对应值,就判定为被遮挡。

下面给出一段基于深度图的遮挡测试代码,假设已有上一帧降采样深度纹理 prev_depth 和高斯投影后的屏幕坐标与最小深度:

import numpy as np

def occlude_test(sx, sy, radius, gauss_depth, prev_depth, w, h):
    x0 = max(0, int(sx - radius))
    x1 = min(w-1, int(sx + radius))
    y0 = max(0, int(sy - radius))
    y1 = min(h-1, int(sy + radius))
    if x0 > x1 or y0 > y1:
        return False
    region = prev_depth[y0:y1+1, x0:x1+1]
    # 若区域内最浅深度都比高斯深,则高斯被挡
    return float(np.min(region)) < gauss_depth

软件遮挡的误差主要来自深度图分辨率与动态物体。若深度图太粗,远处细小缝隙会误杀后面的高斯;若每帧重渲深度图,又增加额外绘制调用。实践中常用半分辨率深度图配合膨胀处理,并对移动物体做单独标记不参与遮挡,从而在准确率和开销间取得平衡。

两级剔除的协同流水与性能实测

把视锥与遮挡剔除串成两级流水时,顺序很关键:必须先视锥后遮挡。因为遮挡测试需要屏幕空间投影,而视锥外的点投影后坐标无意义,提前用视锥砍掉能大幅减少后续投影与深度比较的次数。在调度上,可让视锥剔除在compute队列完成,再把可见索引传给遮挡阶段,最后才进入高斯排序与泼溅。

我们在一处包含约两百万高斯的城市场景做对比:无剔除时帧率约22 FPS;仅视锥剔除升至41 FPS;再加入半分辨率深度图遮挡剔除达到58 FPS,且主观画面与全量渲染一致。下表列出不同方案的开销占比:

方案平均帧率剔除后剩余高斯比例额外CPU开销
无剔除22 FPS100%0%
仅视锥41 FPS54%3%
视锥+遮挡58 FPS31%7%

可以看到遮挡剔除带来的收益高于视锥,但边际成本也更高。若场景以室外开阔地为主,遮挡收益会明显下降;而在楼宇密集区,遮挡剔除几乎决定了能否实时。工程上建议把深度图更新频率设为每两到三帧一次,并用时间平滑减少闪烁,这样既压住开销又保持视觉稳定。

3DGS视锥剔除遮挡剔除修改时间:2026-08-18 10:54:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。