題:實(shí)時(shí)渲染與可編輯三維重建)
1. 從“渲染一張圖要等半天”說(shuō)起3D Gaussian Splatting 到底解決了什么如果你最近在圖形學(xué)圈子里混大概率躲不開(kāi)3D Gaussian Splatting這個(gè)詞。各種演示視頻里一個(gè)場(chǎng)景從幾十張照片出發(fā)幾分鐘內(nèi)就能在瀏覽器里實(shí)時(shí)旋轉(zhuǎn)、縮放、漫游光影和細(xì)節(jié)還相當(dāng)能打。很多人第一反應(yīng)是“又一個(gè)新玩具”但真正上手做過(guò)三維重建的人會(huì)明白它戳中的是過(guò)去幾年一直沒(méi)被很好解決的一堆痛點(diǎn)。我接觸三維重建和神經(jīng)渲染這條線有幾年了從最早的 NeRF 到后來(lái)的各種加速變體踩過(guò)的坑不算少。3D Gaussian Splatting后面簡(jiǎn)稱 3DGS在 2023 年出現(xiàn)之后我第一時(shí)間跑通了官方實(shí)現(xiàn)也拿自己的數(shù)據(jù)集做了對(duì)比。這篇是系列的第二篇專門聊它到底解決了什么問(wèn)題——不是復(fù)述論文而是從一個(gè)實(shí)際使用者的角度把“為什么它值得關(guān)注”講清楚。先說(shuō)結(jié)論3DGS 解決的核心問(wèn)題是在保持高質(zhì)量渲染的前提下把訓(xùn)練速度和渲染速度同時(shí)拉到了實(shí)時(shí)級(jí)別并且用一種顯式、可編輯的場(chǎng)景表示繞開(kāi)了神經(jīng)隱式表示在工程落地上的很多麻煩。它適合誰(shuí)看如果你在做三維重建、數(shù)字孿生、虛擬場(chǎng)景搭建、AR/VR 內(nèi)容或者只是對(duì)“從照片生成可漫游三維場(chǎng)景”感興趣這篇應(yīng)該能幫你理清它和 NeRF 那條路線的本質(zhì)差異。2. 先搞清楚 3DGS 出現(xiàn)之前大家卡在哪里2.1 NeRF 的輝煌與它的“慢”要理解 3DGS 解決了什么得先回到它要挑戰(zhàn)的對(duì)象——NeRFNeural Radiance Fields神經(jīng)輻射場(chǎng)。NeRF 的思路非常優(yōu)雅用一個(gè)多層感知機(jī)MLP去擬合一個(gè)連續(xù)函數(shù)輸入是空間坐標(biāo)和觀察方向輸出是那個(gè)點(diǎn)的顏色和密度。渲染的時(shí)候沿著光線采樣把采樣點(diǎn)的顏色和密度積分起來(lái)就得到像素值。這個(gè)思路在 2020 年橫空出世時(shí)確實(shí)驚艷畫質(zhì)細(xì)膩、視角一致性好尤其是對(duì)反光和半透明材質(zhì)的處理傳統(tǒng)方法很難做到。但問(wèn)題也很致命訓(xùn)練慢、渲染慢。原始 NeRF 訓(xùn)一個(gè)場(chǎng)景要一兩天渲染一幀要幾十秒甚至更久。原因在于每渲染一個(gè)像素都要在光線上采樣上百個(gè)點(diǎn)每個(gè)點(diǎn)都要過(guò)一遍 MLP計(jì)算量爆炸。后來(lái)出現(xiàn)了一堆加速方案比如把場(chǎng)景切成網(wǎng)格、用哈希編碼、用更小的網(wǎng)絡(luò)、做重要性采樣等等。這些方法確實(shí)把訓(xùn)練時(shí)間壓到了幾分鐘到幾十分鐘渲染也能到接近實(shí)時(shí)。但代價(jià)是實(shí)現(xiàn)復(fù)雜度飆升顯存占用大而且很多加速結(jié)構(gòu)本身很難編輯。你沒(méi)法簡(jiǎn)單地“刪掉場(chǎng)景里的一個(gè)物體”或者“把某個(gè)區(qū)域換個(gè)顏色”因?yàn)檎麄€(gè)場(chǎng)景是耦合在一個(gè)神經(jīng)網(wǎng)絡(luò)或者哈希表里的。2.2 傳統(tǒng)顯式重建的“糙”另一條路是傳統(tǒng)的顯式重建比如點(diǎn)云、網(wǎng)格、體素。這些表示的好處是直觀、可編輯、渲染管線成熟。但問(wèn)題在于從多視角照片重建出高質(zhì)量的點(diǎn)云或網(wǎng)格非常困難。點(diǎn)云稀疏、有噪聲網(wǎng)格重建容易丟細(xì)節(jié)尤其是對(duì)細(xì)薄結(jié)構(gòu)、透明物體、復(fù)雜紋理傳統(tǒng)方法往往力不從心。而且渲染質(zhì)量高度依賴幾何精度幾何一糙畫面就崩。所以過(guò)去幾年的局面是隱式表示畫質(zhì)好但慢且難編輯顯式表示快且可編輯但畫質(zhì)糙。大家一直在等一個(gè)能兼顧兩者的方案。2.3 3DGS 的破局點(diǎn)用“一堆高斯球”表示場(chǎng)景3DGS 的核心洞察其實(shí)很樸素既然隱式表示難編輯、顯式表示畫質(zhì)糙那能不能用一種既顯式、又能表達(dá)連續(xù)輻射場(chǎng)的表示答案是用一堆三維高斯分布來(lái)拼出整個(gè)場(chǎng)景。每個(gè)高斯有自己的位置、協(xié)方差決定形狀和朝向、不透明度以及用球諧函數(shù)表示的顏色跟視角有關(guān)。渲染的時(shí)候把這些高斯投影到屏幕上按深度排序然后做 alpha 混合。整個(gè)過(guò)程是可微的所以可以用照片做監(jiān)督通過(guò)梯度下降去優(yōu)化每個(gè)高斯的參數(shù)。這個(gè)設(shè)計(jì)一下子把幾個(gè)問(wèn)題同時(shí)解決了表示是顯式的每個(gè)高斯就是一個(gè)可操作單元渲染是光柵化式的天然適合 GPU 并行優(yōu)化是端到端的畫質(zhì)能逼近甚至超過(guò) NeRF。下面我拆開(kāi)講它具體解決了哪些問(wèn)題。3. 3DGS 到底解決了哪些具體問(wèn)題3.1 訓(xùn)練速度從“按天算”到“按分鐘算”這是最直觀的改進(jìn)。官方實(shí)現(xiàn)里一個(gè)中等復(fù)雜度的場(chǎng)景訓(xùn)練時(shí)間通常在幾分鐘到十幾分鐘取決于照片數(shù)量和分辨率。我實(shí)測(cè)過(guò)一個(gè)約 100 張照片的室內(nèi)場(chǎng)景在單張消費(fèi)級(jí)顯卡上跑了大概 8 分鐘就收斂得不錯(cuò)了。對(duì)比原始 NeRF 動(dòng)輒一兩天這是數(shù)量級(jí)的提升。為什么能這么快關(guān)鍵在于沒(méi)有神經(jīng)網(wǎng)絡(luò)推理的瓶頸。NeRF 每次采樣都要過(guò) MLP而 3DGS 的“前向”主要是高斯的投影和混合這些都是高度并行的矩陣運(yùn)算GPU 非常擅長(zhǎng)。反向傳播也只需要更新高斯參數(shù)不涉及深層網(wǎng)絡(luò)。再加上它用了自適應(yīng)密度控制——在細(xì)節(jié)多的地方分裂高斯在空曠區(qū)域裁剪高斯——讓高斯數(shù)量保持在合理范圍不會(huì)無(wú)謂地浪費(fèi)算力。實(shí)操心得訓(xùn)練速度對(duì)硬件很敏感尤其是顯存帶寬。同樣的場(chǎng)景顯存大的卡能開(kāi)更高分辨率、更多高斯收斂更快。如果顯存吃緊可以適當(dāng)降低初始點(diǎn)云密度但別降太狠否則細(xì)節(jié)恢復(fù)會(huì)變差。3.2 渲染速度真正的實(shí)時(shí)漫游訓(xùn)練快只是第一步渲染快才是 3DGS 真正出圈的原因。官方演示里1080p 分辨率下渲染幀率能到 100 FPS 以上甚至更高。這意味著你可以在普通筆記本上流暢地旋轉(zhuǎn)、縮放、漫游一個(gè)從照片重建出來(lái)的場(chǎng)景延遲低到幾乎感覺(jué)不到。這背后是光柵化管線的功勞。高斯投影到屏幕后按 tile 分塊每個(gè) tile 內(nèi)做深度排序和 alpha 混合整個(gè)過(guò)程跟傳統(tǒng)游戲渲染的思路很像天然適合 GPU。相比之下NeRF 的體渲染需要沿光線采樣即使加速后也很難做到穩(wěn)定高幀率。我拿同一個(gè)場(chǎng)景分別用加速版 NeRF 和 3DGS 渲染過(guò)NeRF 大概能到 20-30 FPS而 3DGS 輕松跑滿 60 FPS 以上而且畫質(zhì)沒(méi)有明顯下降。對(duì)于需要交互的應(yīng)用比如虛擬看房、文物展示、游戲場(chǎng)景預(yù)覽這個(gè)差距是決定性的。3.3 顯式表示帶來(lái)的可編輯性這是我覺(jué)得被很多人低估的一點(diǎn)。因?yàn)閳?chǎng)景是一堆獨(dú)立的高斯你可以直接對(duì)它們做操作刪掉一部分高斯就等于刪掉一個(gè)物體移動(dòng)一組高斯就能移動(dòng)物體改顏色、改不透明度都很直接。這在 NeRF 里幾乎是不可能輕松做到的因?yàn)樾畔⒎稚⒃诰W(wǎng)絡(luò)的權(quán)重里。舉個(gè)例子我做場(chǎng)景清理時(shí)想把重建結(jié)果里的一些漂浮噪點(diǎn)去掉。在 3DGS 里我可以按高斯的不透明度或者尺寸篩選把明顯異常的高斯刪掉重新渲染立刻見(jiàn)效。而在 NeRF 里你只能重新訓(xùn)練或者調(diào)網(wǎng)絡(luò)非常麻煩。這種可編輯性對(duì)下游應(yīng)用意義很大數(shù)字內(nèi)容創(chuàng)作、場(chǎng)景編輯、物理仿真接入都變得可行。你可以把 3DGS 場(chǎng)景導(dǎo)出跟傳統(tǒng)渲染管線結(jié)合甚至做動(dòng)態(tài)編輯。3.4 畫質(zhì)不輸 NeRF某些場(chǎng)景更好早期有人擔(dān)心顯式表示畫質(zhì)會(huì)糙但實(shí)際對(duì)比下來(lái)3DGS 在多數(shù)場(chǎng)景下畫質(zhì)跟 NeRF 持平在細(xì)節(jié)豐富、紋理復(fù)雜的場(chǎng)景里甚至更好。因?yàn)樗么罅扛咚谷M合細(xì)節(jié)不像 MLP 那樣容易過(guò)平滑。尤其是對(duì)高頻紋理、細(xì)薄結(jié)構(gòu)3DGS 恢復(fù)得更銳利。當(dāng)然它也有短板比如對(duì)鏡面反射、透明折射的處理不如 NeRF 自然因?yàn)楦咚贡旧聿簧瞄L(zhǎng)表達(dá)這些復(fù)雜光路。但社區(qū)已經(jīng)在改進(jìn)比如結(jié)合環(huán)境貼圖、引入反射項(xiàng)等。整體來(lái)說(shuō)畫質(zhì)已經(jīng)足夠滿足大多數(shù)應(yīng)用需求。3.5 工程落地的友好度從工程角度看3DGS 的部署門檻低很多。訓(xùn)練好的場(chǎng)景就是一組高斯參數(shù)可以存成文件加載到渲染器里直接畫。不需要帶著一個(gè)神經(jīng)網(wǎng)絡(luò)推理框架到處跑也不需要擔(dān)心不同硬件上 MLP 的數(shù)值差異。渲染器可以用 CUDA 寫也可以用 WebGL/WebGPU 做瀏覽器端渲染社區(qū)已經(jīng)有多個(gè)開(kāi)源實(shí)現(xiàn)。這對(duì)產(chǎn)品化很關(guān)鍵。NeRF 方案往往要綁定特定的推理后端部署復(fù)雜、優(yōu)化困難。而 3DGS 更接近傳統(tǒng)圖形管線的思路容易集成到現(xiàn)有引擎里比如 Unity、Unreal 都有相關(guān)插件在冒出來(lái)。4. 它沒(méi)解決什么邊界與注意事項(xiàng)4.1 顯存和存儲(chǔ)占用高斯數(shù)量可以很大一個(gè)精細(xì)場(chǎng)景可能有幾百萬(wàn)甚至上千萬(wàn)個(gè)高斯每個(gè)高斯要存位置、協(xié)方差、顏色、不透明度等參數(shù)存儲(chǔ)和顯存占用都不小。我遇到過(guò)一些場(chǎng)景訓(xùn)練完模型文件好幾百 MB加載到顯存里也吃緊。雖然社區(qū)有壓縮方案比如量化、剪枝但這是它相比 NeRF 的一個(gè)劣勢(shì)——NeRF 的模型文件通常小得多。注意如果你的應(yīng)用對(duì)包體大小敏感比如移動(dòng)端或者網(wǎng)頁(yè)端需要提前評(píng)估高斯數(shù)量和壓縮策略。別等到部署時(shí)才發(fā)現(xiàn)加載不動(dòng)。4.2 對(duì)初始點(diǎn)云的依賴3DGS 通常從稀疏點(diǎn)云比如用 SfM 工具生成初始化。如果初始點(diǎn)云質(zhì)量差、覆蓋不全重建效果會(huì)受影響。它雖然有自適應(yīng)密度控制但沒(méi)法憑空變出缺失區(qū)域的結(jié)構(gòu)。所以前期拍照和 SfM 的質(zhì)量仍然很重要不是隨便拍幾張就能出好結(jié)果。4.3 動(dòng)態(tài)場(chǎng)景和光照變化原始 3DGS 假設(shè)場(chǎng)景是靜態(tài)的、光照固定的。如果場(chǎng)景里有運(yùn)動(dòng)物體或者拍攝時(shí)曝光變化大重建會(huì)出現(xiàn)鬼影或顏色不一致。后續(xù)有很多工作在做動(dòng)態(tài) 3DGS、可重光照 3DGS但都還在演進(jìn)中。如果你要做的是動(dòng)態(tài)內(nèi)容需要選對(duì)應(yīng)的變體不能直接用原版。4.4 反射和透明材質(zhì)的挑戰(zhàn)前面提過(guò)高斯本身不擅長(zhǎng)表達(dá)鏡面反射和折射。對(duì)于玻璃、水面、金屬這類材質(zhì)3DGS 容易顯得“糊”或者不真實(shí)。這是它相比 NeRF 的一個(gè)明顯短板也是當(dāng)前研究的熱點(diǎn)。5. 一張表看清 3DGS 與 NeRF 的差異維度NeRF 類方法3D Gaussian Splatting場(chǎng)景表示隱式神經(jīng)網(wǎng)絡(luò)顯式高斯集合訓(xùn)練時(shí)間幾分鐘到幾十小時(shí)幾分鐘到十幾分鐘渲染速度通常較慢加速后接近實(shí)時(shí)實(shí)時(shí)輕松高幀率畫質(zhì)優(yōu)秀反射透明處理好優(yōu)秀細(xì)節(jié)銳利反射透明較弱可編輯性差信息耦合在網(wǎng)絡(luò)里好可單獨(dú)操作高斯存儲(chǔ)占用較小較大依賴高斯數(shù)量部署難度較高依賴推理框架較低接近傳統(tǒng)圖形管線動(dòng)態(tài)場(chǎng)景需專門變體需專門變體這張表不是要分高下而是幫你判斷什么場(chǎng)景該選什么。要極致畫質(zhì)和復(fù)雜光路NeRF 系仍有優(yōu)勢(shì)要實(shí)時(shí)交互、可編輯、快速迭代3DGS 更合適。6. 實(shí)操中容易踩的坑與排查思路6.1 訓(xùn)練出來(lái)一片模糊或者有大量漂浮物這通常跟初始點(diǎn)云質(zhì)量和訓(xùn)練步數(shù)有關(guān)。先檢查 SfM 輸出的點(diǎn)云是否覆蓋了場(chǎng)景主要區(qū)域如果點(diǎn)太稀疏可以調(diào)高 SfM 的密度或者換更好的拍攝方式。訓(xùn)練步數(shù)不夠也會(huì)導(dǎo)致高斯沒(méi)收斂適當(dāng)增加迭代次數(shù)。漂浮物多半是背景區(qū)域的高斯沒(méi)被裁掉可以在訓(xùn)練后按不透明度或尺寸過(guò)濾。6.2 渲染時(shí)幀率上不去先看高斯數(shù)量是不是太多。幾百萬(wàn)個(gè)高斯在低端卡上確實(shí)吃力??梢試L試剪枝去掉不透明度低的高斯或者對(duì)遠(yuǎn)處的高斯做簡(jiǎn)化。另外渲染分辨率也是關(guān)鍵降低分辨率能顯著提升幀率。如果用的是瀏覽器端渲染檢查是否開(kāi)了硬件加速。6.3 顏色在不同視角下不一致這往往是曝光變化或者白平衡不一致導(dǎo)致的。拍攝時(shí)盡量鎖定曝光和白平衡或者后期做顏色校正。3DGS 對(duì)輸入照片的一致性比較敏感前期多花點(diǎn)時(shí)間處理照片后期省很多事。6.4 模型文件太大加載慢可以用量化把參數(shù)從 32 位浮點(diǎn)壓到 16 位甚至 8 位或者做高斯合并把相似的高斯合并成一個(gè)。社區(qū)有現(xiàn)成工具但要注意壓縮后畫質(zhì)會(huì)有些損失需要權(quán)衡。實(shí)操心得我習(xí)慣在訓(xùn)練完后先做一輪可視化檢查把明顯異常的高斯手動(dòng)刪掉再導(dǎo)出。這樣模型更干凈加載也快。別小看這一步能省掉很多下游調(diào)試時(shí)間。7. 它適合你的項(xiàng)目嗎幾個(gè)判斷標(biāo)準(zhǔn)如果你在做需要實(shí)時(shí)交互的三維展示比如虛擬展廳、房產(chǎn)漫游、文物數(shù)字化3DGS 幾乎是當(dāng)前最優(yōu)解。如果你需要從照片快速迭代場(chǎng)景比如做概念設(shè)計(jì)、場(chǎng)景預(yù)覽它的訓(xùn)練速度能讓你一天試很多版。如果你需要對(duì)場(chǎng)景做編輯比如刪物體、換材質(zhì)它的顯式表示會(huì)讓你輕松很多。但如果你要做的是動(dòng)態(tài)人物、復(fù)雜反射、大范圍戶外場(chǎng)景或者對(duì)存儲(chǔ)體積極其敏感那可能需要等對(duì)應(yīng)的變體成熟或者結(jié)合其他方案。技術(shù)選型沒(méi)有銀彈關(guān)鍵是看清自己的核心需求。我個(gè)人在實(shí)際項(xiàng)目里的體會(huì)是3DGS 最大的價(jià)值不是某一項(xiàng)指標(biāo)碾壓而是它把高質(zhì)量重建的門檻拉低了一大截。以前要搭一套 NeRF 管線、調(diào)各種參數(shù)、等很久才能看到結(jié)果現(xiàn)在幾分鐘就能出一個(gè)可交互的場(chǎng)景這種反饋速度對(duì)創(chuàng)作和迭代的幫助是巨大的。后續(xù)這個(gè)系列我還會(huì)聊具體的訓(xùn)練配置、參數(shù)調(diào)優(yōu)和部署方案感興趣可以繼續(xù)關(guān)注。