Warning, /frameworks/kirigami/src/scenegraph/shaders6/sdf_lowpower.glsl is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
0002 // SPDX-FileCopyrightText: 2017 Inigo Quilez
0003 //
0004 // SPDX-License-Identifier: MIT
0005 //
0006 // This file is based on
0007 // https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
0008 
0009 //if not GLES
0010 // include "desktop_header.glsl"
0011 //else
0012 // include "es_header.glsl"
0013 
0014 // A maximum point count to be used for sdf_polygon input arrays.
0015 // Unfortunately even function inputs require a fixed size at declaration time
0016 // for arrays, unless we were to use OpenGL 4.5.
0017 // Since the polygon is most likely to be defined in a uniform, this should be
0018 // at least less than MAX_FRAGMENT_UNIFORM_COMPONENTS / 2 (since we need vec2).
0019 #define SDF_POLYGON_MAX_POINT_COUNT 400
0020 
0021 /*********************************
0022     Shapes
0023 *********************************/
0024 
0025 // Distance field for a circle.
0026 //
0027 // \param point A point on the distance field.
0028 // \param radius The radius of the circle.
0029 //
0030 // \return The signed distance from point to the circle. If negative, point is
0031 //         inside the circle.
0032 lowp float sdf_circle(in lowp vec2 point, in lowp float radius)
0033 {
0034     return length(point) - radius;
0035 }
0036 
0037 // Distance field for a triangle.
0038 //
0039 // \param point A point on the distance field.
0040 // \param p0 The first vertex of the triangle.
0041 // \param p0 The second vertex of the triangle.
0042 // \param p0 The third vertex of the triangle.
0043 //
0044 // \note The ordering of the three vertices does not matter.
0045 //
0046 // \return The signed distance from point to triangle. If negative, point is
0047 //         inside the triangle.
0048 lowp float sdf_triangle(in lowp vec2 point, in lowp vec2 p0, in lowp vec2 p1, in lowp vec2 p2)
0049 {
0050     lowp vec2 e0 = p1 - p0;
0051     lowp vec2 e1 = p2 - p1;
0052     lowp vec2 e2 = p0 - p2;
0053 
0054     lowp vec2 v0 = point - p0;
0055     lowp vec2 v1 = point - p1;
0056     lowp vec2 v2 = point - p2;
0057 
0058     lowp vec2 pq0 = v0 - e0 * clamp( dot(v0, e0) / dot(e0, e0), 0.0, 1.0 );
0059     lowp vec2 pq1 = v1 - e1 * clamp( dot(v1, e1) / dot(e1, e1), 0.0, 1.0 );
0060     lowp vec2 pq2 = v2 - e2 * clamp( dot(v2, e2) / dot(e2, e2), 0.0, 1.0 );
0061 
0062     lowp float s = sign( e0.x*e2.y - e0.y*e2.x );
0063     lowp vec2 d = min(min(vec2(dot(pq0,pq0), s*(v0.x*e0.y-v0.y*e0.x)),
0064                           vec2(dot(pq1,pq1), s*(v1.x*e1.y-v1.y*e1.x))),
0065                           vec2(dot(pq2,pq2), s*(v2.x*e2.y-v2.y*e2.x)));
0066 
0067     return -sqrt(d.x)*sign(d.y);
0068 }
0069 
0070 // Distance field for a rectangle.
0071 //
0072 // \param point A point on the distance field.
0073 // \param rect A vec2 with the size of the rectangle.
0074 //
0075 // \return The signed distance from point to rectangle. If negative, point is
0076 //         inside the rectangle.
0077 lowp float sdf_rectangle(in lowp vec2 point, in lowp vec2 rect)
0078 {
0079     lowp vec2 d = abs(point) - rect;
0080     return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
0081 }
0082 
0083 // Distance field for a rectangle with rounded corners.
0084 //
0085 // \param point The point to calculate the distance of.
0086 // \param rect The rectangle to calculate the distance of.
0087 // \param radius A vec4 with the radius of each corner. Order is top right, bottom right, top left, bottom left.
0088 //
0089 // \return The signed distance from point to rectangle. If negative, point is
0090 //         inside the rectangle.
0091 lowp float sdf_rounded_rectangle(in lowp vec2 point, in lowp vec2 rect, in lowp vec4 radius)
0092 {
0093     radius.xy = (point.x > 0.0) ? radius.xy : radius.zw;
0094     radius.x = (point.y > 0.0) ? radius.x : radius.y;
0095     lowp vec2 d = abs(point) - rect + radius.x;
0096     return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)) - radius.x;
0097 }
0098 
0099 /*********************
0100     Operators
0101 *********************/
0102 
0103 // Convert a distance field to an annular (hollow) distance field.
0104 //
0105 // \param sdf The result of an sdf shape to convert.
0106 // \param thickness The thickness of the resulting shape.
0107 //
0108 // \return The value of sdf modified to an annular shape.
0109 lowp float sdf_annular(in lowp float sdf, in lowp float thickness)
0110 {
0111     return abs(sdf) - thickness;
0112 }
0113 
0114 // Union two sdf shapes together.
0115 //
0116 // \param sdf1 The first sdf shape.
0117 // \param sdf2 The second sdf shape.
0118 //
0119 // \return The union of sdf1 and sdf2, that is, the distance to both sdf1 and
0120 //         sdf2.
0121 lowp float sdf_union(in lowp float sdf1, in lowp float sdf2)
0122 {
0123     return min(sdf1, sdf2);
0124 }
0125 
0126 // Subtract two sdf shapes.
0127 //
0128 // \param sdf1 The first sdf shape.
0129 // \param sdf2 The second sdf shape.
0130 //
0131 // \return sdf1 with sdf2 subtracted from it.
0132 lowp float sdf_subtract(in lowp float sdf1, in lowp float sdf2)
0133 {
0134     return max(sdf1, -sdf2);
0135 }
0136 
0137 // Intersect two sdf shapes.
0138 //
0139 // \param sdf1 The first sdf shape.
0140 // \param sdf2 The second sdf shape.
0141 //
0142 // \return The intersection between sdf1 and sdf2, that is, the area where both
0143 //         sdf1 and sdf2 provide the same distance value.
0144 lowp float sdf_intersect(in lowp float sdf1, in lowp float sdf2)
0145 {
0146     return max(sdf1, sdf2);
0147 }
0148 
0149 // Smoothly intersect two sdf shapes.
0150 //
0151 // \param sdf1 The first sdf shape.
0152 // \param sdf2 The second sdf shape.
0153 // \param smoothing The amount of smoothing to apply.
0154 //
0155 // \return A smoothed version of the intersect operation.
0156 lowp float sdf_intersect_smooth(in lowp float sdf1, in lowp float sdf2, in lowp float smoothing)
0157 {
0158     lowp float h = clamp(0.5 - 0.5 * (sdf1 - sdf2) / smoothing, 0.0, 1.0);
0159     return mix(sdf1, sdf2, h) + smoothing * h * (1.0 - h);
0160 }
0161 
0162 // Round an sdf shape.
0163 //
0164 // \param sdf The sdf shape to round.
0165 // \param amount The amount of rounding to apply.
0166 //
0167 // \return The rounded shape of sdf.
0168 //         Note that rounding happens by basically selecting an isoline of sdf,
0169 //         therefore, the resulting shape may be larger than the input shape.
0170 lowp float sdf_round(in lowp float sdf, in lowp float amount)
0171 {
0172     return sdf - amount;
0173 }
0174 
0175 // Convert an sdf shape to an outline of its shape.
0176 //
0177 // \param sdf The sdf shape to turn into an outline.
0178 //
0179 // \return The outline of sdf.
0180 lowp float sdf_outline(in lowp float sdf)
0181 {
0182     return abs(sdf);
0183 }
0184 
0185 /********************
0186     Convenience
0187 ********************/
0188 
0189 // A constant to represent a "null" value of an sdf.
0190 //
0191 // Since 0 is a point exactly on the outline of an sdf shape, and negative
0192 // values are inside the shape, this uses a very large positive constant to
0193 // indicate a value that is really far away from the actual sdf shape.
0194 const lowp float sdf_null = 99999.0;
0195 
0196 // A constant for a default level of smoothing when rendering an sdf.
0197 //
0198 // This
0199 const lowp float sdf_default_smoothing = 0.625;
0200 
0201 // Render an sdf shape alpha-blended onto an existing color.
0202 //
0203 // This is an overload of sdf_render(float, vec4, vec4) that allows specifying a
0204 // blending amount and a smoothing amount.
0205 //
0206 // \param alpha The alpha to use for blending.
0207 // \param smoothing The amount of smoothing to apply to the sdf.
0208 //
0209 lowp vec4 sdf_render(in lowp float sdf, in lowp vec4 sourceColor, in lowp vec4 sdfColor, in lowp float alpha, in lowp float smoothing)
0210 {
0211     lowp float g = smoothing * fwidth(sdf);
0212     return mix(sourceColor, sdfColor, alpha * (1.0 - clamp(sdf / g, 0.0, 1.0)));
0213 }
0214 
0215 // Render an sdf shape.
0216 //
0217 // This will render the sdf shape on top of whatever source color is input,
0218 // making sure to apply smoothing if desired.
0219 //
0220 // \param sdf The sdf shape to render.
0221 // \param sourceColor The source color to render on top of.
0222 // \param sdfColor The color to use for rendering the sdf shape.
0223 //
0224 // \return sourceColor with the sdf shape rendered on top.
0225 lowp vec4 sdf_render(in lowp float sdf, in lowp vec4 sourceColor, in lowp vec4 sdfColor)
0226 {
0227     return sdf_render(sdf, sourceColor, sdfColor, 1.0, sdf_default_smoothing);
0228 }
0229 
0230 // Render an sdf shape.
0231 //
0232 // This is an overload of sdf_render(float, vec4, vec4) that allows specifying a
0233 // smoothing amount.
0234 //
0235 // \param smoothing The amount of smoothing to apply to the sdf.
0236 //
0237 lowp vec4 sdf_render(in lowp float sdf, in lowp vec4 sourceColor, in lowp vec4 sdfColor, in lowp float smoothing)
0238 {
0239     return sdf_render(sdf, sourceColor, sdfColor, 1.0, smoothing);
0240 }