如何在 WebGL 中创建合适的圆角矩形? [英] How to create a proper rounded rectangle in WebGL?

查看:53
本文介绍了如何在 WebGL 中创建合适的圆角矩形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现

解决方案

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

float smoothedAlpha =1.0 - smoothstep(-edgeSoftness, edgeSoftness, abs(distance) - 厚度);

完整的 shadertoy 着色器(

//来自 http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htmfloat roundedBoxSDF(vec2 CenterPosition, vec2 Size, float Radius){返回长度(max(abs(CenterPosition)-Size+Radius,0.0))-Radius;}void mainImage(out vec4 fragColor, in vec2 fragCoord){vec2 大小 = vec2(300.0, 200.0);vec2 位置 = iMouse.xy;浮动厚度 = 5.0;浮动阴影柔软度 = 30.0f;vec2 shadowOffset = vec2(10.0, -10.0);浮动边缘柔软度 = 1.0;浮动半径 = (sin(iTime*2.0) + 1.0) * 30.0 + 厚度 * 2.0;浮动距离 = roundedBoxSDF(location - fragCoord.xy, size/2.0, radius);float smoothedAlpha = 1.0 - smoothstep(-edgeSoftness, edgeSoftness, abs(distance) - 厚度);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);}

I have tried to implement the answer from this question but there seems to be a bit of a problem. If you open their ShaderToys and try changing the border radius, the size (width and height) of the rounded rectangle change as well.

I'm looking for a solution like this shadertoy where changing the border radius doesn't change the size of the shape. Unfortunately in this shader toy, it's a filled in rounded rectangle.

Is it possible to have a non-filled in rounded rectangle (so, only the border), but also have it such that if you change the border radius that the shape doesn't grow or shrink size?

I'm looking to implement a similar effect to CSS where you can specify the border-radius of a div and it only changes the border's radius without also changing the size of the shape.

Here's an image demonstrating the problem. The left result was with boxRounding set to 0.5 and the right result was with boxRounding set to 0.20. Notice how they're a much different size. Is there any way to make both shapes the same size, but just with a different border radius?

解决方案

For a rectangular outline you have to compute the absolut value of the fragment to the outline:

float smoothedAlpha = 
    1.0 - smoothstep(-edgeSoftness, edgeSoftness, abs(distance) - thickness);

Complete shadertoy shader (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);
}

这篇关于如何在 WebGL 中创建合适的圆角矩形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆