參考:
https://www.bilibili.com/video/BV1MF4m1V7e3/
https://blog.csdn.net/2401_86810419/article/details/148811121
https://www.bilibili.com/video/BV1cz421872F?t=233.9
https://wuli.wiki/online/SphHar.html
https://zhuanlan.zhihu.com/p/467466131
特別指出的是SY__007的3DGS較真系列,對本文有極大的啟發和參考價值,下文有很多截圖也直接來自視頻,強烈推薦大家移步小破站,去觀看視頻。
做雪球?
What is splatting?
關于Splat,在英語中作拋雪球打擊到墻面的擬聲詞。
Splatting是一種體渲染的方法:將3D物體渲染到2D平面
與NeRF中的渲染方法的差異:
NeRF中使用Ray-casting(類似射線求積分):是計算像素點收到發光粒子的影響來生成圖像。
3DGS中使用Splatting這種主動的方法,計算發光粒子如何影響像素點
Splatting算法的核心:
1.選擇雪球
2.拋擲雪球:從3D投影到2D,得到足跡(footprint)
3.加以合成,得到最終的圖像
一:為什么使用核(雪球,Gaussian):
基于Gaussian的數學性質:
1.Gaussian本身是閉合的橢球,經過仿射變換后依舊是封閉的
2.高維Gaussian降維(沿某個軸進行積分)之后依舊是Gaussian
對于橢球Gaussian:
其中x是三維空間中的點,
μ是高斯分布的均值向量,表示Gaussian的中心點位置
Σ是協方差矩陣,描述Gaussian在3D空間中的形狀和方向,它是半正定的
為什么這是一個橢球?
首先去了解 協方差矩陣。
對于Gauss分布:
一維:形狀由 均值&方差 決定
高維:形狀由 均值&協方差矩陣 決定
對于協方差矩陣:
-
是一個對稱矩陣,決定高斯分布形狀
-
對角線上元素為x軸/y軸/z軸的方差
-
反斜對角線上的值為協方差,表示x和y,x和z........的線性相關程度
這里直接用SY__007寫的:
拋雪球
如何進行參數變換?
從3D->像素的過程:
觀測變換
觀測變換:從世界坐標系-->相機坐標系
投影變換
投影變換:正交投影 、透視投影
正交投影:
對于立方體[l,r]*[b,t]*[f,n]
1.平移到原點
2.立方體縮放至[-1,1]^3的正方體空間內
總的來說就是進行了仿射變換,
如題所給的例子的仿射變換即是:
A這里是縮放矩陣
B為平移矩陣
在正交投影中,我們沒有考慮對于原本的長方體的長和寬的比例不同,導致的縮放比例不同,其實產生了畸變,這個問題會在之后的視口變換解決
透視投影:
透視投影需要滿足近大遠小的條件
對于視錐,我們先把他變換為‘立方體’,再進行正交投影
數學過程實在懶得寫了,這里直接放上作者手稿一張
問題?:
透視投影是非線性的,也就是非放射變換,但是高斯橢球經過仿射變換后是高斯,但非仿射變換就不一定。
???????
視口變換:
我們從簡化的圖形渲染管線開始:
3D 頂點 → 模型變換 → 視圖變換 → 投影變換 → 裁剪 → 標準化設備坐標 → 視口變換 → 屏幕像素
之前的變換已經將頂點從”模型局部坐標“轉換成NDC空間坐標,以OpenGL為例,正交投影下為[-1,1]×[-1,1]×[-1,1]
視口變換的目的就是把可見區域的標準化坐標,映射到顯示器的實際像素區域,讓圖形真正顯示在屏幕上。
視口變換的數學實現
核心是縮放+平移的組合,把NDC范圍映射到屏幕視口的像素范圍:
(1)以OpenGL經典的[-1.1]立方體為例(xy對應屏幕二維,z用于深度緩沖):
-
NDC的x范圍:
-
NDC的y范圍:
-
NDC的z范圍:
(或者[0,1],這取決于深度緩沖裝置)
(2)目標視口的像素范圍
假設屏幕視口的:
-
左下角像素坐標:(x0,y0)(比如窗口內視口偏移,或全屏時 (0,0))
-
寬度:width(像素數,如 800 )、高度:height(像素數,如 600 )
-
深度范圍(可選,用于深度緩沖):[zNear,zFar](比如 [0,255] 或浮點深度 )
(3)視口變換矩陣與公式
視口變換通過縮放矩陣+平移矩陣,實現對標準化坐標,變換后得到屏幕像素坐標
用矩陣形式(齊次坐標下)可以表示為:
對于進行拆解
1.縮放部分:
-
x方向:
把[-1,1]縮放為[0,width]范圍;
-
y方向:
把[-1,1]縮放為[0,height]范圍,但考慮到屏幕坐標系一般y軸"向下為上”(與NDC相反),所以使用
反轉;
-
z方向:
把[-1,1]縮放為[zNear,zFar](深度緩沖的實際范圍)
2.平移部分
-
x 平移
,讓縮放后的 [0,width] 起點對齊視口左下角 x0;
-
y 平移
,同理對齊視口左下角 y0;
-
z 平移
,讓縮放后的深度對齊 zNear 起點。
視口變換的實際作用:
-
從虛擬坐標到物理屏幕
-
支持多視角渲染
-
深度緩沖的落地
光柵化:
1.光柵化的位置:渲染管線‘矢量-->像素’轉換
簡單渲染管線流程為:
3D 頂點 → 變換(模型/視圖/投影)→ 裁剪 → 標準化設備坐標(NDC)→ 光柵化 → 像素著色 → 幀緩沖 → 屏幕
-
前面的變換,把頂點轉成抽象的數學坐標(如NDC空間下的[-1,1]立方體)
-
光柵化要解決:如何把這些矢量圖元拆解成屏幕上的離散像素,讓每個像素知道“屬于哪個圖元,該染什么顏色”
2.光柵化的核心任務:圖元的“離散化”
(1)輸入:圖元的“數學描述”
以三角形為例(圖形學的最基礎圖元,復雜模型由三角形拼接),輸入是三個頂點的坐標(NDC或視口變換后的屏幕坐標),以及頂點附帶的屬性(顏色、法向量、紋理坐標等)。
(2)輸出:像素的“歸屬與屬性”
輸出是覆蓋這些三角形的所有像素,并為每個像素插值計算屬性(比如/頂點顏色查指出像素顏色,紋理坐標插值出采樣位置),供后續像素著色器處理。
3.光柵化的關鍵步驟
(1)三角形 setup(配置)
計算三角形的邊方程和包圍盒
-
先找出三角形在屏幕上的最小包圍矩形(AABB),只遍歷這個范圍內的像素,減少計算量;
-
推導三角形三條邊的數學方程(如ax+by+c=0),用于判斷i像素是否在三角形內
(2)三角形traversal(遍歷)
-
對包圍盒捏的每個像素(或'采樣點'),用便方程判斷是否在三角形內(比如OpenGL的“winding order”規則,或計算重心坐標)。
-
若像素在三角形內,就標記為屬于該三角形,并進入屬性插值階段
(3)屬性插值
三角形三個頂點有屬性(如顏色、紋理坐標