REF:
https://www.iquilezles.org/www/articles/distance/distance.htm
一般求完f = SDF = 0,也就是等位面=0时候得 iossurface,平常做raymarching渲染用sdf渲染求交最方便。
这篇文章给了一个 叫做 "距离估算" ,实际上是zero-isosurface to x point distance.
数学原理比较简单:
在houdini测试了下如下:
float smoothstep(float a; float b; float x){ if (x<a) return 0.0f; if (x>=b) return 1.0f; float y = (x-a) / (b-a); return pow(y,2) *(3.0- 2.0 *y); } float f(vector pos) { float r = length(pos); float a = atan(pos.y,pos.x); return r - 1.0 + 0.5*sin(3.0*a + 2.0*r*r); } // grad dx=dy=dz float dx = 0.01; float xpos_l = @P.x + dx; float xpos_r = @P.x - dx; float ypos_l = @P.y + dx; float ypos_r = @P.y - dx; float zpos_l = @P.z + dx; float zpos_r = @P.z - dx; float gradx = ( f(set(xpos_l, @P.y, @P.z)) - f(set(xpos_r, @P.y, @P.z)) ) / (2 * dx); float grady = ( f(set(@P.x, ypos_l, @P.z)) - f(set(@P.x, ypos_r, @P.z)) ) / (2 * dx); float gradz = ( f(set(@P.x, @P.y, zpos_l)) - f(set(@P.x, @P.y, zpos_r)) ) / (2 * dx); vector g = set(gradx,grady,gradz); //@Cd = g; //g = normalize(g); float v = f(@P); float de = abs(v) / length(g); // distance estimation float eps = ch("distance"); //@Cd = smooth(1.9 * eps , 2.0 *eps , abs(v) ); @Cd = 1 - smooth(1 * eps , 2.0 *eps, de);