Geometry 计算点和矩形之间的有符号距离

Geometry 计算点和矩形之间的有符号距离,geometry,glsl,shader,euclidean-distance,Geometry,Glsl,Shader,Euclidean Distance,我试图在GLSL中编写一个函数,返回矩形的有符号距离。矩形与轴对齐。我觉得有点卡住了;我就是不知道该怎么做才能让它工作 我想到的最好的办法是: float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br) { // signed distances for x and y. these work fine. float dx = max(tl.x - uv.x, uv.x - br.x); float dy = max(tl.y -

我试图在GLSL中编写一个函数,返回矩形的有符号距离。矩形与轴对齐。我觉得有点卡住了;我就是不知道该怎么做才能让它工作

我想到的最好的办法是:

float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br)
{
    // signed distances for x and y. these work fine.
    float dx = max(tl.x - uv.x, uv.x - br.x);
    float dy = max(tl.y - uv.y, uv.y - br.y);
    dx = max(0.,dx);
    dy = max(0.,dy);
    return sqrt(dx*dx+dy*dy);
}
这将生成一个矩形,如下所示:

这些线显示与矩形的距离。它工作正常,但仅适用于矩形以外的距离。矩形内的距离是静态的
0.

如何使用统一的公式获得矩形内的精确距离?

这个如何

float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br)
{
    vec2 d = max(tl-uv, uv-br);
    return length(max(vec2(0.0), d)) + min(0.0, max(d.x, d.y));
}
这是,绿色表示正距离,红色表示负距离(代码如下):


细分:

  • 获取从x和y边界的有符号距离
    u-左
    right-u
    是两个x轴距离。取这些值中的最大值可以得到到最近边界的有符号距离。查看
    d.x
    d.y
    分别显示在下图中

  • 组合x和y:

  • 如果两个值均为负值,则取最大值(即最接近边框)。这是通过
    min(0.0,max(d.x,d.y))
    完成的

  • 如果只有一个值为正数,这就是我们想要的距离

  • 如果两个值都为正值,则最近的点是一个角点,在这种情况下,我们需要长度。这可以与上述情况相结合,方法是无论如何取长度,并确保两个值均为正值:
    length(max(vec2(0.0),d))

  • 方程的这两部分是互斥的,即只有一部分会产生非零值,并且可以求和



    杰出的这项工作做得很好。@jozxyqk你是怎么想出这个函数的?@v.shashenko试错法。我更新了答案,让它更详细一些。
    void mainImage( out vec4 fragColor, in vec2 fragCoord )
    {
        vec2 uv = fragCoord.xy / iResolution.xy;
        uv -= 0.5;
        uv *= vec2(iResolution.x/iResolution.y,1.0);
        uv += 0.5;
        float d = sdAxisAlignedRect(uv, vec2(0.3), vec2(0.7));
        float m = 1.0 - abs(d)/0.1;
        float s = sin(d*400.0) * 0.5 + 0.5;
        fragColor = vec4(s*m*(-sign(d)*0.5+0.5),s*m*(sign(d)*0.5+0.5),0,1);
    }