如何在 WebGL 中创建合适的圆角矩形?
How to create a proper rounded rectangle in WebGL?
我已经尝试实现 的答案,但似乎有点问题。如果您打开他们的 ShaderToys 并尝试更改边框半径,圆角矩形的大小(宽度和高度)也会更改。
我正在寻找类似 this shadertoy 的解决方案,其中更改边框半径不会更改形状的大小。不幸的是,在这个着色器玩具中,它是一个填充的圆角矩形。
是否可以有一个非填充的圆角矩形(所以,只有边框),但是 也 有这样的,如果你改变边框半径,形状尺寸没有变大或变小?
我希望实现与 CSS 类似的效果,您可以在其中指定 div
的 border-radius
,它只会更改边框的半径,而不会同时更改 div
的大小形状。
这是一张演示问题的图片。左边的结果是 boxRounding
设置为 0.5
,右边的结果是 boxRounding
设置为 0.20
。请注意它们的大小有很大不同。有什么方法可以使两个形状大小相同,但边界半径不同?
对于矩形轮廓,您必须计算片段与轮廓的绝对值:
float smoothedAlpha =
1.0 - smoothstep(-edgeSoftness, edgeSoftness, abs(distance) - thickness);
完整的 shadertoy 着色器 (2D rounded rectangular outline ):
// 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);
}
我已经尝试实现
我正在寻找类似 this shadertoy 的解决方案,其中更改边框半径不会更改形状的大小。不幸的是,在这个着色器玩具中,它是一个填充的圆角矩形。
是否可以有一个非填充的圆角矩形(所以,只有边框),但是 也 有这样的,如果你改变边框半径,形状尺寸没有变大或变小?
我希望实现与 CSS 类似的效果,您可以在其中指定 div
的 border-radius
,它只会更改边框的半径,而不会同时更改 div
的大小形状。
这是一张演示问题的图片。左边的结果是 boxRounding
设置为 0.5
,右边的结果是 boxRounding
设置为 0.20
。请注意它们的大小有很大不同。有什么方法可以使两个形状大小相同,但边界半径不同?
对于矩形轮廓,您必须计算片段与轮廓的绝对值:
float smoothedAlpha =
1.0 - smoothstep(-edgeSoftness, edgeSoftness, abs(distance) - thickness);
完整的 shadertoy 着色器 (2D rounded rectangular outline ):
// 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);
}