正六邊形的距離場The SDF of a Regular Hexagon
因?yàn)閕q大佬最新更新了cool S的距離場,而我一直對距離場感興趣,可網(wǎng)上除了iq公布的segment line、圓形和方形以外2D和3D距離場其實(shí)都很少都有文章,為了跟上大佬的腳步,最近推算了一下iquilezles大佬的正六邊形距離場。

因?yàn)槲沂强创a分析的,所以我只能把代碼每一行都拆開來做解釋
const vec3 k = vec3(-0.866025404,0.5,0.577350269);
首先這里的-0.866025404,0.5,0.577350269分別是Cos(150°),Sin(30°)和tan(30°)
p = abs(p);
這里把二維坐標(biāo)系折疊因?yàn)榱呅伟凑誼和y軸切都是對稱的所以我們的坐標(biāo)系變成了這樣

p -= 2.0*min(dot(k.xy,p),0.0)*k.xy;
k.xy是如圖所示的藍(lán)色的單位矢量,而min函數(shù)直角和銳角全部排除在外所以受到計(jì)算影響的只有從0°~60°的黃色區(qū)域

減去2.0乘以k.xy和phong模型的specular function的reflect方法相似主要是把黃色區(qū)域全部都沿著k.xy向上移動(dòng)映射到60°~120°這個(gè)時(shí)候整個(gè)坐標(biāo)系就壓縮成了我畫的的紅色區(qū)域

p -= vec2(clamp(p.x, -k.z*r, k.z*r), r);
這里我們把p-vec2分開來看作p.x-clamp(p.x, -k.z*r, k.z*r)和p.y-r
p.y-r就是求出y的距離場
p.x-clamp(p.x, -k.z*r, k.z*r)中-k.z*r和k.z*r k.z之前寫過了是tan(30°)
接下來是最難的一步這里把r想象成cos按照三角形函數(shù)tan=sin/cos這里就把cos相同的矢量也就是p.y相同的矢量的+-p.x限制在p.x-k.z*r,?k.z*r這個(gè)sin(+-30°)*magnitude(長度)中間,也就是說當(dāng)p.x-p.x等于0(在內(nèi)部)時(shí)只判斷你的p.y(青藍(lán)色的線段),只有p.x大于小于+-k.z*r,p.x在外部時(shí)才會有作用會變得越來越圓(深紅色線段)

return length(p)*sign(p.y);
最后返回距離這里的sign(p.y)是為了判斷距離場外面還是內(nèi)部(內(nèi)部都是負(fù)數(shù))
按照這個(gè)方法其實(shí)已經(jīng)可以推算出很多2D距離場了因?yàn)檎暹呅魏驼噙呅味碱愃?當(dāng)然如果你對計(jì)算機(jī)圖形學(xué)感興趣對shadertoy感興趣可以關(guān)注我不定期更新一些圖形學(xué)知識。