Created
December 2, 2019 19:20
-
-
Save all-iver/59423ee929475d0792f5dcd004a05254 to your computer and use it in GitHub Desktop.
Custom round rectangle in Shapes2D
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
float4 _Roundness; // tl, tr, bl, br | |
fixed4 customRect(v2f i, float2 pos) { | |
float radius = min(_XScale, _YScale); | |
float distToCircle = radius - distance(float2(abs(pos.x), pos.y), float2(_XScale / 2 - radius, _YScale / 2)); | |
float distToSide = _YScale / 2 - abs(pos.y); | |
float dist = when_ge(abs(pos.x), _XScale / 2 - radius) * min(distToSide, distToCircle) | |
+ when_le(abs(pos.x), _XScale / 2 - radius) * distToSide; | |
fixed4 color = color_from_distance(dist, fill(i.uv), _OutlineColor) * i.color; | |
if (_PreMultiplyAlpha == 1) | |
color.rgb *= color.a; | |
if (_UseClipRect == 1) | |
color.a *= UnityGet2DClipping(i.modelPos.xy, _ClipRect); | |
clip(color.a - 0.001); | |
return color; | |
} | |
fixed4 frag(v2f i) : SV_Target { | |
float2 pos = prepare(i.uv, i.modelPos.z); | |
if (_Roundness.x == 0 && _Roundness.y == 0 && _Roundness.z > 0 && _Roundness.w > 0) | |
return customRect(i, pos); | |
// get the roundness for this corner in world units, avoiding conditionals because | |
// they tend to break things on various platforms (gles3) and they are slow in | |
// shaders anyway | |
float tl = and(when_le(pos.x, 0), when_ge(pos.y, 0)) * _Roundness.x; | |
float tr = and(when_ge(pos.x, 0), when_ge(pos.y, 0)) * _Roundness.y; | |
float bl = and(when_le(pos.x, 0), when_le(pos.y, 0)) * _Roundness.z; | |
float br = and(when_ge(pos.x, 0), when_le(pos.y, 0)) * _Roundness.w; | |
float roundness = tl + tr + bl + br; | |
// radius of the circle at this corner, making sure not to go past halfway | |
float radius = min(min(_XScale / 2, roundness), _YScale / 2); | |
// handy distance to round rectangle formula | |
float2 extents = float2(_XScale, _YScale) / 2 - radius; | |
float2 delta = abs(pos) - extents; | |
// first component is distance to closest side when not in a corner circle, second | |
// is distance to the rounded part when in a corner circle | |
float dist = radius - (min(max(delta.x, delta.y), 0) + length(max(delta, 0))); | |
fixed4 color = color_from_distance(dist, fill(i.uv), _OutlineColor) * i.color; | |
if (_PreMultiplyAlpha == 1) | |
color.rgb *= color.a; | |
if (_UseClipRect == 1) | |
color.a *= UnityGet2DClipping(i.modelPos.xy, _ClipRect); | |
clip(color.a - 0.001); | |
return color; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment