我想通了一段時間以前,廣泛在博客中寫到這裏一下:http://fabricecastel.github.io/blog/2016-02-11/main.html
下面是摘錄(見全文後更全面的解釋):
考慮四點,A,B,C和D.讓我們粗略地減少距離函數來嘗試去除最小/最大函數以瞭解它們的效果(因爲這是令人費解的關於這個函數的)。下面的符號有點草率,我用方括號來表示2D矢量。
// 2D version of the function
d(p) = min(max(p.x, p.y), 0)
+ length(max(p, 0))
---
d(A) = min(max(-1, -1), 0)
+ length(max([-1, -1], 0))
d(A) = -1 + length[0, 0]
---
d(B) = min(max(1, 1), 0)
+ length(max([1, 1], 0))
d(B) = 0 + length[1, 1]
好的,到目前爲止沒有什麼特別的。當A位於正方形內部時,我們基本上得到了基於平面/線的第一個距離函數,當B位於第一個距離函數不準確的區域時,它被歸零並得到第二個距離函數(長度)。訣竅在於C和D的另外兩種情況。讓我們來解決它們。
d(C) = min(max(-1, 1), 0)
+ length(max([-1, 1], 0))
d(C) = 0 + length[0, 1]
---
d(D) = min(max(1, -1), 0)
+ length(max([-1, 1], 0))
d(D) = 0 + length[1, 0]
如果你回頭看上面的圖表,你會注意到C'和D'。這些點分別具有座標[0,1]和[1,0]。這種方法使用兩個距離場在軸上相交的事實 - D和D'與正方形距離相同。
如果我們將矢量的所有負向分量零點並取其長度,我們將得到點與正方形之間的正確距離(僅適用於正方形以外的點)。這是max(d,0.0)所做的;一個組件式的最大操作。只要向量具有至少一個正分量,min(max(d.x,d.y),0.0)將解析爲0,只留下等式的第二部分。如果點在方格內,我們想返回方程的第一部分(因爲它表示我們的第一個距離函數)。如果載體的所有成分都是陰性,很容易看到我們的狀況會得到滿足。
這種理解應該在您將頭圍繞它時無縫地變回到3D。你可能會也可能不需要親手繪製幾張圖來真正「獲取」它 - 我知道我做過了,如果你對我的解釋不滿意,會鼓勵你這樣做。
這個工作落實到我們自己的代碼,我們得到這樣的:
float distanceToNearestSurface(vec3 p){
float s = 1.0;
vec3 d = abs(p) - vec3(s);
return min(max(d.x, max(d.y,d.z)), 0.0)
+ length(max(d,0.0));
}
有你有它。