Implicit隐式渲染入门 SDF SphereTracing
Implicit
何為隱式?隱式(Implicit)的是顯式(explicit)的反義詞。
explicit可以簡單理解為用網(wǎng)格等信息描述的幾何形狀,網(wǎng)格信息是離散的,信息量越大描述越精準。Implicit則不需要頂點等顯式信息,用方程,或者說有符號距離場 (Signed Distance Field) 即SDF,表示幾何形狀的數(shù)學(xué)模型。
SDF
在SDF中,空間中的每一點都有一個值,表示該點到最近表面的距離。這個距離可以是正的(如果點在形狀的外部),也可以是負的(如果點在形狀的內(nèi)部)。SDF提供了一種簡潔而強大的方式來描述復(fù)雜的三維形狀,包括難以用傳統(tǒng)多邊形網(wǎng)格表示的形狀。
SDF的優(yōu)勢:
- 高效的幾何操作:進行布爾運算以及形狀變形和平滑處理變得簡單高效。
- 復(fù)雜形狀的表示:特別適合描述復(fù)雜或有機形狀,如流體、云霧和生物組織。
- 動態(tài)變化的支持:使實時更新和變形成為可能。
對幾何primitive的sdf描述
Inigo Quilez :: computer graphics, mathematics, shaders, fractals, demoscene and more (iquilezles.org)
Sphere Tracing
why
傳統(tǒng)的光線追蹤算法,通過發(fā)送光線并檢測這些光線與場景中物體的交點,進行著色。但是當(dāng)場景使用SDF來表示時,傳統(tǒng)的交點檢測方法不再適用。原因在于SDF和多邊形網(wǎng)格表示場景的方式截然不同:
- 頂點表示:在傳統(tǒng)的多邊形網(wǎng)格表示中,物體由許多小的平面片(通常是三角形)構(gòu)成的。這些三角形有明確的邊界和頂點,因此當(dāng)光線與這些三角形相交時,可以通過數(shù)學(xué)計算找到精確的交點。
- SDF表示:相比之下,SDF場景被視為一個連續(xù)的體。體中每個點都有一個值,表示該點到最近表面的距離。這種表示方法不涉及明確的邊界或頂點,而是提供關(guān)于形狀表面的連續(xù)信息。
由于SDF沒有離散的多邊形或邊界,傳統(tǒng)的光線與多邊形的交點檢測算法(通常涉及線性代數(shù)和平面幾何計算)不再適用。在SDF表示的場景中,沒有明確的多邊形表面可以直接與光線進行交點計算。因此需要Sphere Tracing這樣的算法來處理SDF場景。
How
原版的SphereTracing十分討巧,其基本原理非常簡潔,也非常聰明:
- 從點 \(p_0\) 開始投射一條 ray,以 SDF 值?\(f(p_0)\) 為步長進行一次 marching。
- 以上次 marching 的終點為起點,以?\(f(p_1)\) 為步長繼續(xù)下一次 marching。
- 重復(fù) marching 直到?\(f(p_n)\) < \(\epsilon\) , \(\epsilon\) 為預(yù)設(shè)的閾值。此時我們認為 \(f(p_n)\) 即為交點。
Enhanced Sphere Tracing
上述的傳統(tǒng) Sphere Tracing 算法冗余的步進次數(shù)很多,為了進一步提高效率,誕生了很多種優(yōu)化方案。
binary search 二分查找法,實際效果不理想,并且遇上TPMS這種復(fù)雜結(jié)構(gòu)會有更多問題
Inigo Quilez :: computer graphics, mathematics, shaders, fractals, demoscene and more (iquilezles.org)
Segment Tracing 通過假設(shè)場景是?\(C^2\)?連續(xù)去加長初始 marching 的距離,有效減少 marching 次數(shù)的同時,大幅提升了每次 marching 的消耗,效果不理想,并且在有棱角的場景表現(xiàn)更差
https://diglib.eg.org/bitstream/handle/10.1111/cgf13951/v39i2pp545-554.pdf
GitHub - aparis69/Segment-Tracing: Source code for the Computer Graphics Forum paper: Segment Tracing Using Local Lipschitz Bounds. Presented at Eurographics 2020.
【光線追蹤】Segment Tracing:一種可能加速距離場求交的實時光線追蹤方案 - 知乎 (zhihu.com)
Enhanced Sphere Tracing 采用激進的 marching 步長,即設(shè)定一個步長倍數(shù)\(\alpha\) ,marching 步長改為 \(f(p_n) * \alpha\) 而不是 Sphere Tracing 保守的 \(f(p_n)\) 。只要兩個 sphere 相交,就說明本次 marching 可安全,否則退回到點 \(p_n\) 的位置重新進行保守的 marching。
Accelerating Sphere Tracing 在 enhanced 的基礎(chǔ)上更進一步。假設(shè)前兩次 marching 所形成的 sphere 都相切于同一平面,那么下一次可以嘗試 marching 同樣與該平面相切并且也與上一次的 marching sphere 相切的距離。同樣,如果嘗試失敗則回退至保守 marching。
上述兩個方法都是在2023年以前最優(yōu)秀的 marching 算法之一,直到 Automatic Step Size Relaxation。
Automatic step size relaxation
Automatic step size relaxation 可以根據(jù)歷史 marching 的情況,動態(tài)調(diào)整步長:平面多的地方。可以走相切平面的激進步長,而曲面多的地方則調(diào)整為走更保守的步長。
每次 marching 不斷更新近似斜率?m,然后用它來指導(dǎo)下一次 marching。
博主拙劣的C++實現(xiàn)
auto trace_auto_relaxation = [&](glm::vec3 p)
{
float t = 0.0f;
float r = sdf(p);
float m = -1.0f;
float z = r;
const float beta = 0.3f;
for (int i = 0; i < max_steps; i++)
{
if (r < eps) {
return true;
}
if (t + r > max_dist) {
break;
}
glm::vec3 next_p = p + ray_dir * z * relaxation_factor;
float R = sdf(next_p);
bool doBackStep = z > abs(R) + r;
if (!doBackStep) {
float M = (R - r) / (z + 1e-5f);
m = (1.0f - beta) * m + beta * M;
t += z * relaxation_factor;
p = next_p;
r = R;
}
else {
m = -1.0f;
}
float omega = glm::max(1.0f, 2.0f / (1.0f - m));
z = glm::max(eps, r * omega);
}
return false;
};
But
講完了嗎?講完我要開始轉(zhuǎn)了。
上述的所有方法,對 TPMS(Triply Periodic Minimal Surfaces 三周期極小曲面),都起不到多少作用。目前效果最好的辦法只能是力大磚飛——marching 步長乘以系數(shù) \(\alpha ,\alpha < 1\) ,以非常保守的步長去小心翼翼的找TPMS表面。也是博主目前最頭疼的問題,歡迎討論。
總結(jié)
以上是生活随笔為你收集整理的Implicit隐式渲染入门 SDF SphereTracing的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 创建傀儡进程svchost.exe并注入
- 下一篇: 文心一言 VS 讯飞星火 VS chat