* @details Name "cornerSquareness", type Property::FLOAT or Property::VECTOR4, animatable
* @note By default, it is Vector::ZERO.
* @note Each squareness will clamp internally as [0.0 1.0].
- * @note If squareness is not zero, the width of borderline might not equal with it's real value.
* @note Squareness value are used in clockwise order from top-left-corner to bottom-left-corner.
* When squareness is Vector4(x, y, z, w)
* x y
void calculatePotential()
{
#ifdef IS_REQUIRED_SQUIRCLE_CORNER
+ // If gSquareness is near 1.0, it make some numeric error. Let we avoid this situation by heuristic value.
+ if(gSquareness > 0.99)
+ {
+ gPotential = max(gDiff.x, gDiff.y);
+ return;
+ }
+
// We need to found the r value s.t. x^2 + y^2 - s/r/r x^2y^2 = r^2
// and check this r is inside [gRadius - vAliasMargin, gRadius + vAliasMargin]
highp vec2 positiveDiff = max(gDiff, 0.0);
- // If gSquareness is near 1.0, it make some numeric error. Let we avoid this situation by heuristic value.
- if(gSquareness > 0.99)
- {
- gPotential = max(gDiff.x, gDiff.y);
- return;
- }
-
// make sqr to avoid duplicate codes.
positiveDiff *= positiveDiff;
#elif defined(IS_REQUIRED_BORDERLINE)
lowp vec4 convertBorderlineColor(lowp vec4 textureColor)
{
- // TODO : Need to consider squareness
-
highp float potential = gPotential;
// default opacity of borderline is 0.0
void calculatePotential()
{
#ifdef IS_REQUIRED_SQUIRCLE_CORNER
+ // If gSquareness is near 1.0, it make some numeric error. Let we avoid this situation by heuristic value.
+ if(gSquareness > 0.99)
+ {
+ gPotential = max(gDiff.x, gDiff.y);
+ return;
+ }
+
// We need to found the r value s.t. x^2 + y^2 - s/r/r x^2y^2 = r^2
// and check this r is inside [gRadius - vAliasMargin, gRadius + vAliasMargin]
highp vec2 positiveDiff = max(gDiff, 0.0);
- // If gSquareness is near 1.0, it make some numeric error. Let we avoid this situation by heuristic value.
- if(gSquareness > 0.99)
- {
- gPotential = max(gDiff.x, gDiff.y);
- return;
- }
-
// make sqr to avoid duplicate codes.
positiveDiff *= positiveDiff;
#ifdef IS_REQUIRED_BORDERLINE
lowp vec4 convertBorderlineColor(lowp vec4 textureColor)
{
- // TODO : Need to consider squareness
-
highp float potential = gPotential;
// default opacity of borderline is 0.0
void calculatePotential()
{
#ifdef IS_REQUIRED_SQUIRCLE_CORNER
+ // If gSquareness is near 1.0, it make some numeric error. Let we avoid this situation by heuristic value.
+ if(gSquareness > 0.99)
+ {
+ gPotential = max(gDiff.x, gDiff.y);
+ return;
+ }
+
// We need to found the r value s.t. x^2 + y^2 - s/r/r x^2y^2 = r^2
// and check this r is inside [gRadius - vAliasMargin, gRadius + vAliasMargin]
highp vec2 positiveDiff = max(gDiff, 0.0);
- // If gSquareness is near 1.0, it make some numeric error. Let we avoid this situation by heuristic value.
- if(gSquareness > 0.99)
- {
- gPotential = max(gDiff.x, gDiff.y);
- return;
- }
-
// make sqr to avoid duplicate codes.
positiveDiff *= positiveDiff;
#ifdef IS_REQUIRED_BORDERLINE
lowp vec4 convertBorderlineColor(lowp vec4 textureColor)
{
- // TODO : Need to consider squareness
-
highp float potential = gPotential;
// default opacity of borderline is 0.0
}
// from https://iquilezles.org/articles/distfunctions
-float roundedBoxSDF(vec2 PixelPositionFromCenter, vec2 RectangleEdgePositionFromCenter, float Radius, float Squareness) {
- highp vec2 positiveDiff = max(PixelPositionFromCenter
- - RectangleEdgePositionFromCenter
- + Radius
- , 0.0);
+float roundedBoxSDF(vec2 pixelPositionFromCenter, vec2 rectangleEdgePositionFromCenter, float radius, float squareness) {
+ highp vec2 diff = pixelPositionFromCenter
+ - rectangleEdgePositionFromCenter
+ + radius;
- highp float squrenessFactor = Squareness / max(1.0, Radius * Radius);
+ // If squareness is near 1.0 or 0.0, it make some numeric error. Let we avoid this situation by heuristic value.
+ if(squareness < 0.01)
+ {
+ return length(max(diff, 0.0)) + min(0.0, max(diff.x, diff.y)) - radius;
+ }
+ if(squareness > 0.99)
+ {
+ return max(diff.x, diff.y) - radius;
+ }
+
+ highp vec2 positiveDiff = max(diff, 0.0);
// make sqr to avoid duplicate codes.
positiveDiff *= positiveDiff;
- return sqrt(positiveDiff.x + positiveDiff.y - squrenessFactor * positiveDiff.x * positiveDiff.y)
- - Radius;
+ // TODO : Could we remove this double-sqrt code?
+ return sqrt(((positiveDiff.x + positiveDiff.y)
+ + sqrt(positiveDiff.x * positiveDiff.x
+ + positiveDiff.y * positiveDiff.y
+ + (2.0 - 4.0 * squareness) * positiveDiff.x * positiveDiff.y))
+ * 0.5)
+ + min(0.0, max(diff.x, diff.y)) ///< Consider negative potential, to avoid visual defect when radius is zero
+ - radius;
}
void main()
mix(vCornerRadius.w, vCornerRadius.z, sign(location.x) * 0.5 + 0.5),
sign(location.y) * 0.5 + 0.5
);
- float squareness =
- mix(
- mix(uCornerSquareness.x, uCornerSquareness.y, sign(location.x) * 0.5 + 0.5),
- mix(uCornerSquareness.w, uCornerSquareness.z, sign(location.x) * 0.5 + 0.5),
- sign(location.y) * 0.5 + 0.5
- );
float edgeSoftness = min(1.0, radius);
}
else
{
- float distance = roundedBoxSDF(location, halfSize, radius, squareness);
+ float squareness =
+ mix(
+ mix(uCornerSquareness.x, uCornerSquareness.y, sign(location.x) * 0.5 + 0.5),
+ mix(uCornerSquareness.w, uCornerSquareness.z, sign(location.x) * 0.5 + 0.5),
+ sign(location.y) * 0.5 + 0.5
+ );
+
+ float signedDistance = roundedBoxSDF(location, halfSize, radius, squareness);
- float smoothedAlpha = 1.0 - smoothstep(-edgeSoftness, edgeSoftness, distance);
+ float smoothedAlpha = 1.0 - smoothstep(-edgeSoftness, edgeSoftness, signedDistance);
// Premultiply alpha feature used.
gl_FragColor *= smoothedAlpha;
mFactoryCache,
ImageVisualShaderFeature::FeatureBuilder()
.ApplyDefaultTextureWrapMode(defaultWrapMode)
- .EnableRoundedCorner(IsRoundedCornerRequired())
+ .EnableRoundedCorner(IsRoundedCornerRequired(), IsSquircleCornerRequired())
.EnableBorderline(IsBorderlineRequired())
.EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering));
return shader;
shader = mImageVisualShaderFactory.GetShader(
mFactoryCache,
ImageVisualShaderFeature::FeatureBuilder()
- .EnableRoundedCorner(IsRoundedCornerRequired())
+ .EnableRoundedCorner(IsRoundedCornerRequired(), IsSquircleCornerRequired())
.EnableBorderline(IsBorderlineRequired())
.SetTextureForFragmentShaderCheck(mUseNativeImage ? mImpl->mRenderer.GetTextures().GetTexture(0) : Dali::Texture()));
}
mFactoryCache,
ImageVisualShaderFeature::FeatureBuilder()
.EnableTextureAtlas(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED)
- .EnableRoundedCorner(IsRoundedCornerRequired())
+ .EnableRoundedCorner(IsRoundedCornerRequired(), IsSquircleCornerRequired())
.EnableBorderline(IsBorderlineRequired()));
}
else