如何在 WebGL 中创建合适的圆角矩形?

Rya*_*hel 3 shader glsl webgl opengl-es-2.0

我试图实现这个问题的答案,但似乎有点问题。如果您打开他们的 ShaderToys 并尝试更改边框半径,圆角矩形的大小(宽度和高度)也会发生变化。

我正在寻找像这个 Shadertoy这样的解决方案,其中更改边框半径不会改变形状的大小。不幸的是,在这个着色器玩具中,它是一个填充的圆角矩形。

是否可以有一个未填充的圆角矩形(因此,只有边框),但可以在更改边框半径时使形状不会增大或缩小?

我正在寻求实现与 CSS 类似的效果,您可以在其中指定border-radiusa div,它只会更改边框的半径,而不会更改形状的大小。

这是演示该问题的图像。左边的结果是boxRounding设置为0.5,右边的结果是boxRounding设置为0.20。注意它们的大小有很大不同。有什么方法可以使两个形状具有相同的大小,但具有不同的边框半径?

在此输入图像描述

Rab*_*d76 7

对于矩形轮廓,您必须计算片段与轮廓的绝对值:

float smoothedAlpha = 
    1.0 - smoothstep(-edgeSoftness, edgeSoftness, abs(distance) - thickness);
Run Code Online (Sandbox Code Playgroud)

完整的shadertoy着色器(2D圆角矩形轮廓):

// from http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
float roundedBoxSDF(vec2 CenterPosition, vec2 Size, float Radius)
{
    return length(max(abs(CenterPosition)-Size+Radius,0.0))-Radius;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2  size           = vec2(300.0, 200.0);
    vec2  location       = iMouse.xy;
    float thickness      = 5.0;
    float shadowSoftness = 30.0f;
    vec2  shadowOffset   = vec2(10.0, -10.0);
    float edgeSoftness   = 1.0;
    float radius         = (sin(iTime*2.0) + 1.0) * 30.0 + thickness * 2.0;
    
    float distance       = roundedBoxSDF(location - fragCoord.xy, size/2.0, radius);
    float smoothedAlpha  = 1.0 - smoothstep(-edgeSoftness, edgeSoftness, abs(distance) - thickness);
    vec4  quadColor      = mix(vec4(1.0), vec4(0.0, 0.2, 1.0, smoothedAlpha), smoothedAlpha);
    
    float shadowDistance = roundedBoxSDF(location + shadowOffset - fragCoord.xy, size/2.0, radius);
    float shadowAlpha    = 1.0 - smoothstep(-shadowSoftness/2.0, shadowSoftness/2.0, abs(shadowDistance));
    vec4 shadowColor     = vec4(0.4, 0.4, 0.4, 1.0);
    fragColor            = mix(quadColor, shadowColor, shadowAlpha - smoothedAlpha);
}
Run Code Online (Sandbox Code Playgroud)