Shadertoy效果(十三)再说opengl与signed distance function

发现一篇好博客http://jamie-wong.com/2016/07/15/ray-marching-signed-distance-functions/

signed distance function

首先,假设我们要生成一个三维球体,那么三维空间里的哪些点在这个球体内部呢?

比如这个球的中心点坐标是(0,0,0),半径是1,那么对于任意一点x,y,z可以用以下公式判断

如果结果小于0说明在内部,大于0说明在球体外边,这就是符号(signed)的含义。写成程序就是这样

float sphereSDF(vec3 p) {
    return length(p) - 1.0;
}

法向量

简便起见,先说二维的。比如一条紫色曲线的A点(x0 = 10,y0 = 10),怎么知道那点的法向量?

答案是选择一个很小的量。简单起见,这里选一个比较大的量s = 1,计算f(B)= f(x1 = x0 + s = 11,y1 = y0 = 10),C在另一方向上类似。

三维方向上则是

写成代码

vec3 estimateNormal(vec3 p) {
    return normalize(vec3(
        sceneSDF(vec3(p.x + EPSILON, p.y, p.z)) - sceneSDF(vec3(p.x - EPSILON, p.y, p.z)),
        sceneSDF(vec3(p.x, p.y + EPSILON, p.z)) - sceneSDF(vec3(p.x, p.y - EPSILON, p.z)),
        sceneSDF(vec3(p.x, p.y, p.z  + EPSILON)) - sceneSDF(vec3(p.x, p.y, p.z - EPSILON))
    ));
}

RayMarching

图解如下。网上资料很多这里就不再赘述了。实际更常用的算法是RayTracing。

发布了194 篇原创文章 · 获赞 8 · 访问量 9879

猜你喜欢

转载自blog.csdn.net/qq_43439240/article/details/103730742