distance estimation

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);
View Code

猜你喜欢

转载自www.cnblogs.com/gearslogy/p/11434897.html