欢迎光临散文网 会员登陆 & 注册

正六边形的距离场The SDF of a Regular Hexagon

2023-06-25 00:22 作者:海豹_Chili  | 我要投稿

因为iq大佬最新更新了cool S的距离场,而我一直对距离场感兴趣,可网上除了iq公布的segment line、圆形和方形以外2D和3D距离场其实都很少都有文章,为了跟上大佬的脚步,最近推算了一下iquilezles大佬的正六边形距离场。

https://iquilezles.org/articles/distfunctions2d/

因为我是看代码分析的,所以我只能把代码每一行都拆开来做解释

  • 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);

    这里把二维坐标系折叠因为六边形按照x和y轴切都是对称的所以我们的坐标系变成了这样

  • p -= 2.0*min(dot(k.xy,p),0.0)*k.xy;

    k.xy是如图所示的蓝色的单位矢量,而min函数直角和锐角全部排除在外所以受到计算影响的只有从0°~60°的黄色区域

减去2.0乘以k.xy和phong模型的specular function的reflect方法相似主要是把黄色区域全部都沿着k.xy向上移动映射到60°~120°这个时候整个坐标系就压缩成了我画的的红色区域


  • 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*rk.z*r k.z之前写过了是tan(30°)

    接下来是最难的一步这里把r想象成cos按照三角形函数tan=sin/cos这里就把cos相同的矢量也就是p.y相同的矢量的+-p.x限制在p.x-k.z*r, k.z*r这个sin(+-30°)*magnitude(长度)中间,也就是说当p.x-p.x等于0(在内部)时只判断你的p.y(青蓝色的线段),只有p.x大于小于+-k.z*r,p.x在外部时才会有作用会变得越来越圆(深红色线段)

画的有点烂懂我意思就行


  • return length(p)*sign(p.y);

    最后返回距离这里的sign(p.y)是为了判断距离场外面还是内部(内部都是负数)

按照这个方法其实已经可以推算出很多2D距离场了因为正五边形和正多边形都类似,当然如果你对计算机图形学感兴趣对shadertoy感兴趣可以关注我不定期更新一些图形学知识。

正六边形的距离场The SDF of a Regular Hexagon的评论 (共 条)

分享到微博请遵守国家法律