3DGS 渲染機制與顯存管理
說明數據以何種方式進入顯存參與渲染,以及顯存的分配規則與容量上限。畫面參數的調節參考畫面調節,加載操作參考快速入門。
術語約定:數據被切分後的最小加載與渲染單位稱為節點(Node);每個節點的精度由 Level 標識,Level 0 精度最高,Level 越大精度越低。該定義與性能優化參數說明一致。
分塊渲染與全量渲染
數據加載後有兩種渲染方式:按需加載可見節點(分塊渲染),或一次性加載整份數據(全量渲染)。默認行為按管線區分:
| 管線 | 格式 | 默認模式 |
|---|---|---|
| LCC2 | .lcc2 / .ply / .spz / .sog | 分塊渲染 |
| LCC | .lcc | 全量渲染;數據量超過閾值時回退為分塊渲染 |
分塊渲染
數據被切分為空間節點,每個節點包含多個 Level。每幀的處理流程如下:
遍歷(按相機位置與朝向篩選可見節點,為每個節點選定 Level)
│
▼
加載(將選中節點的數據讀入內存)
│
▼
上傳(將數據提交至顯存)
│
▼
渲染
近處節點使用低 Level,遠處節點使用高 Level,不可見節點不加載。離開視野的節點不會立即釋放,而是保留在緩存中以便再次進入視野時直接複用;僅在顯存不足時,才依據最後渲染時間等條件淘汰最久未使用的節點。顯存佔用主要取決於當前可見範圍,因此可支撐大規模場景。
兩條管線的繪製提交方式不同:
| 管線 | 繪製方式 |
|---|---|
| LCC | 每個節點單獨提交一次繪製,節點數量增加時繪製調用同步增加 |
| LCC2 | 所有可見節點的數據匯總至統一 Buffer,僅提交一次繪製 |
分塊渲染的固有代價:
- 相鄰節點可能被分配到不同 Level,交界處的疏密與清晰度存在差異,可觀察到節點邊界
- 相機移動過程中 Level 持續切換,可能出現細節跳變
全量渲染
跳過按相機篩選節點的過程,將整份數據一次性加載並常駐顯存,相機移動時不再重新遍歷與選定 Level。
優勢:
- 全場景使用統一 Level,不存在節點間的 Level 差異,無可見的節點邊界
- 數據常駐顯存,相機移動時無加載、釋放與細節跳變
- 省去每幀的遍歷與上傳開銷,幀率更穩定
代價是數據全部常駐顯存,佔用隨場景規模線性增長,因此僅適用於小規模場景。
全量渲染的判定條件
是否啟用全量渲染在加載時確定,取決於 Use Full Load 開關與 Level 0 的 splat 數量:
Load(數據文件)
│
▼
讀取 Level 0 splat 數量
│
▼
Use Full Load 開啟? ── 否 ──▶ 分塊渲染
│ 是
▼
splat 數 ≤ Full Load Splat Number? ── 否 ──▶ 分塊渲染
│ 是
▼
全量渲染
兩個屬性均位於 Actor 的 Details 面板 Performance 分類下:
| 屬性 | 說明 |
|---|---|
| Use Full Load | 是否允許使用全量渲染 |
| Full Load Splat Number | 允許全量渲染的 Level 0 splat 數上限(單位:萬,默認 1500) |
默認值按 Actor 類型區分:
| Actor | Use Full Load 默認值 | 依據 |
|---|---|---|
| ALCCActor | 開啟 | 節點間 Level 差異明顯、節點邊界可見,且每個節點佔用一次繪製調用,小場景採用全量渲染效果更優 |
| ALCC2Actor / APlyActor / ASpzActor / ASogActor | 關閉 | Level 切換按屏幕誤差連續過渡、節點邊界不明顯,且僅需一次繪製調用,默認按需加載更節省顯存 |
LCC2 手動開啟全量渲染的場景
LCC2 管線默認關閉全量渲染,以下場景可手動開啟:
- 場景規模有限、顯存充足,需要畫質與幀率同時穩定
- 相機快速移動或頻繁傳送,節點加載無法跟上,出現空洞或細節跳變
- 產品級展示、錄屏、序列渲染等不接受加載過程中畫面變化的場合
- 節點交界處的疏密差異仍然可見
開啟後若顯存吃緊或幀率下降,表明場景已超出全量渲染的適用範圍,應改回分塊渲染。
注:全量渲染仍受最大渲染距離限制,相機與數據的距離超出該值時不顯示。
顯存預算與容量上限
LCC2 管線將常駐的 splat 數據匯總至統一 Buffer 渲染,因此單個模型可加載的數據量取決於這些 Buffer 的容量上限。
Buffer 結構與單 splat 佔用
數據分兩份 Buffer 存放:
| Buffer | 每個 splat 佔用 | 內容 |
|---|---|---|
| 高斯基礎數據 Buffer | 40 字節 | 位置、旋轉、顏色、縮放 |
| 球諧 Buffer | 48 字節(最高 3 階) | 球諧係數,僅帶球諧的數據才分配 |
單個 Buffer 的硬上限
Unreal 的 Buffer 大小以 32 位整數記錄,理論上限 4 GB。插件實際取 4095 MB(比 4 GB 少 1 MB),保留的餘量用於保證上傳時的字節計算不越界。該上限對每份 Buffer 單獨生效,無法通過設置突破。
顯存預算設置
單個模型可用的顯存由 ProjectSettings > Plugins > LCC4Unreal 中的 LCC2 GPU Memory Budget (MB) 控制:
| 項目 | 值 |
|---|---|
| 默認值 | 2048 MB |
| 可調範圍 | 2048 ~ 8192 MB |
| 生效方式 | 修改後需重啟編輯器 |
該預算為兩份 Buffer 的總額,而非單份上限。因此帶球諧的數據按每 splat 88 字節(40 + 48)計入預算,不帶球諧的按 40 字節計入。
排序 Buffer 的額外開銷
3DGS 渲染前需按 splat 到相機的距離排序,排序結果與視角相關,因此每個視角需單獨一組排序 Buffer。該部分不計入上述預算,每個視角的每個常駐 splat 額外佔用 16 字節(排序鍵與索引各兩份,用於排序過程中的交替讀寫)。
以 2048 MB 預算、帶球諧的數據為例,可常駐約 2440 萬 splat,單視角的排序 Buffer 約 372 MB。
立體渲染的左右眼、分屏的每個玩家、SceneCapture 各計為一個視角。視角數增加時排序 Buffer 隨之增長,且視角減少後不會回落,因此規劃顯存時需按出現過的最大視角數預留。
單文件格式的加載上限
單文件格式指 .ply / .spz / .sog,即整份數據保存在一個文件中、且不包含節點劃分與 Level 信息的格式。這類數據無法拆分加載,插件只能將其作為單一節點一次性解碼並全部常駐顯存,因此存在明確的 splat 數上限。.lcc 與 .lcc2 在導出時已完成節點劃分,不屬於單文件格式。
上限的計算方式
加載前插件會計算上限並對超限數據進行攔截:
| 預算 | 不帶球諧 | 帶球諧 |
|---|---|---|
| 2048 MB(默認) | 約 5300 萬 | 約 2440 萬 |
| 4096 MB | 約 1.07 億 | 約 4470 萬 |
| 8192 MB | 約 1.07 億 | 約 4470 萬 |
上限取以下三個條件中的最小值,顯存預算僅為其中之一:
| 條件 | 說明 |
|---|---|
| 顯存預算 | 預算除以每 splat 字節數(不帶球諧 40 B,帶球諧 88 B) |
| 單 Buffer 上限 | 4095 MB 除以最大 stride(不帶球諧 40 B,帶球諧 48 B) |
| 球諧數組容量 | 僅帶球諧時生效,解碼結果使用 32 位索引,上限約 4470 萬 |
因此預算超過 4096 MB 後數值不再增長:不帶球諧時受限於單 Buffer 上限,帶球諧時受限於球諧數組容量。此外,顯卡實際可用顯存會進一步壓低可加載量。
注:已知問題。預算設置項允許填至 8192 MB,但單文件格式的可加載量在 4096 MB 時已達上限,繼續調高不產生效果且不會給出提示。預算已為 4096 MB 仍超限時,應轉換為
.lcc2或改用不帶球諧的數據。該限制將在後續版本改善。
超出上限時的處理
單文件數據超限時加載會被拒絕,Output Log 中會輸出實際 splat 數、當前上限,以及預算調至最大時可支持的 splat 數。處理辦法按推薦順序:
- 轉換為
.lcc2,由插件按需加載而非一次性常駐。 - 將 LCC2 GPU Memory Budget 調至 4096 MB,重啟後重試。僅在當前瓶頸為預算時有效,調至 8192 MB 對單文件格式無效。
- 改用不帶球諧的數據,每 splat 計入預算的字節數由 88 降至 40。
改用 .sog 或 .spz 無助於突破上限:這類格式的壓縮僅作用於磁盤文件,解碼後每個 splat 在顯存中的佔用完全相同。
LCC2 格式不受此上限約束
.lcc2 將數據切分為多個節點,每個節點單獨解碼與上傳,任何單個節點均遠低於上述上限,因此數據總量沒有硬性上限,可顯著超出顯存預算。受約束的是運行期的兩個量:
| 約束對象 | 限制來源 | 超出時的行為 |
|---|---|---|
| 同時常駐的 splat 數 | 顯存預算與單 Buffer 上限 | 按最久未使用淘汰,換入換出 |
| 單幀渲染的 splat 數 | 約 8900 萬(4095 MB ÷ 48 B) | 按距離丟棄遠處節點 |
單幀渲染量同時受 Actor 的 Max Splat Num 限制,兩者取較小值。
顯存管理與調優
顯存不足時的自動釋放
運行期插件持續監控顯卡的實際顯存佔用。佔用超過 ProjectSettings 中 Max GPU Usage Percentage For Release 設定的比例時,會按最後渲染時間、訪問頻率、數據大小與 Level 綜合排序,優先釋放最久未使用的節點。高 Level 節點受到保護,以避免快速轉動視角時出現大面積空洞。
相關設置:
| 設置 | 說明 |
|---|---|
| Max GPU Usage Percentage For Release | 觸發自動釋放的顯存佔用比例(50 ~ 100%) |
| GPU Release Percentage | 每次觸發時釋放的數據比例(10 ~ 100%) |
| LCC2 GPU Memory Budget (MB) | 單個模型的 splat 數據顯存預算 |
顯存預算不足的判斷與調整
預算偏小時數據不會加載失敗,而是表現為反覆換入換出。常見現象:
- 相機移動或轉動時畫面出現空洞,停止後逐漸補全
- 視角來回擺動時,同一區域反覆變清晰再變模糊
- 局部區域始終偏模糊,靠近後仍不變清晰
- 幀率隨視野內容量波動,視野開闊時明顯下降
- 場景靜止時表現正常,移動時出現卡頓
其中局部偏模糊容易被誤判為數據本身質量不足。低 Level 數據來不及加載時,插件會先以顯存中已有的高 Level 數據填充,保證畫面不空缺,待低 Level 數據就緒後替換。顯存不足導致低 Level 數據反覆被淘汰時,該區域會持續停留在高 Level。判斷依據是靠近後是否變清晰:正常情況下停留一至兩秒即可補全,始終不變則說明低 Level 數據無法進入顯存。
確認方法:查看 Output Log 中加載時輸出的模型預計佔用(predicted cost),與當前預算對比。若單個模型的預計佔用接近或超過預算,說明常駐空間不足。也可通過 stat LCC 觀察釋放次數,數值持續增長表明正在頻繁淘汰。
調高預算的前提是顯卡有餘量。預算僅為插件申請的上限,超出顯卡實際可用顯存後,驅動會將數據交換至系統內存,幀率下降比換入換出更嚴重。調整時按以下順序判斷:
- 確認顯卡可用顯存。預算加上排序 Buffer 的開銷後,應為引擎自身與其他資源保留餘量。
- 逐級調高預算(2048 → 4096 → 8192),每次重啟後觀察空洞與幀率是否改善。
- 改善不明顯時說明瓶頸不在預算,轉為降低數據量:調低 Max Splat Num、啟用 Max Distance 限制,或改用不帶球諧的數據。
注:預算按每個模型獨立計算。場景中放置多個 LCC Actor 時,顯存佔用隨模型數量累加,需相應下調單個模型的預算。