Warning, /frameworks/kquickcharts/src/shaders/sdf.glsl is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2019 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 // A maximum point count to be used for sdf_polygon input arrays. 0010 // Unfortunately even function inputs require a fixed size at declaration time 0011 // for arrays, unless we were to use OpenGL 4.5. 0012 // Since the polygon is most likely to be defined in a uniform, this should be 0013 // at least less than MAX_FRAGMENT_UNIFORM_COMPONENTS / 2 (since we need vec2). 0014 #define SDF_POLYGON_MAX_POINT_COUNT 400 0015 0016 // A constant for pi 0017 const lowp float pi = 3.1415926535897932384626433832795; 0018 0019 /********************************* 0020 Shapes 0021 *********************************/ 0022 0023 // Distance field for a circle. 0024 // 0025 // \param point A point on the distance field. 0026 // \param radius The radius of the circle. 0027 // 0028 // \return The signed distance from point to the circle. If negative, point is 0029 // inside the circle. 0030 lowp float sdf_circle(in lowp vec2 point, in lowp float radius) 0031 { 0032 return length(point) - radius; 0033 } 0034 0035 // Distance field for a triangle. 0036 // 0037 // \param point A point on the distance field. 0038 // \param p0 The first vertex of the triangle. 0039 // \param p0 The second vertex of the triangle. 0040 // \param p0 The third vertex of the triangle. 0041 // 0042 // \note The ordering of the three vertices does not matter. 0043 // 0044 // \return The signed distance from point to triangle. If negative, point is 0045 // inside the triangle. 0046 lowp float sdf_triangle(in lowp vec2 point, in lowp vec2 p0, in lowp vec2 p1, in lowp vec2 p2) 0047 { 0048 lowp vec2 e0 = p1 - p0; 0049 lowp vec2 e1 = p2 - p1; 0050 lowp vec2 e2 = p0 - p2; 0051 0052 lowp vec2 v0 = point - p0; 0053 lowp vec2 v1 = point - p1; 0054 lowp vec2 v2 = point - p2; 0055 0056 lowp vec2 pq0 = v0 - e0 * clamp( dot(v0, e0) / dot(e0, e0), 0.0, 1.0 ); 0057 lowp vec2 pq1 = v1 - e1 * clamp( dot(v1, e1) / dot(e1, e1), 0.0, 1.0 ); 0058 lowp vec2 pq2 = v2 - e2 * clamp( dot(v2, e2) / dot(e2, e2), 0.0, 1.0 ); 0059 0060 lowp float s = sign( e0.x*e2.y - e0.y*e2.x ); 0061 lowp vec2 d = min(min(vec2(dot(pq0,pq0), s*(v0.x*e0.y-v0.y*e0.x)), 0062 vec2(dot(pq1,pq1), s*(v1.x*e1.y-v1.y*e1.x))), 0063 vec2(dot(pq2,pq2), s*(v2.x*e2.y-v2.y*e2.x))); 0064 0065 return -sqrt(d.x)*sign(d.y); 0066 } 0067 0068 #ifndef API_ES2 0069 // Distance field for an arbitrary polygon. 0070 // 0071 // \param point A point on the distance field. 0072 // \param vertices An array of points that make up the polygon. 0073 // \param count The amount of points to use for the polygon. 0074 // 0075 // \note points should be an array of vec2 of size SDF_POLYGON_MAX_POINT_COUNT. 0076 // Use count to indicate how many items of that array should be used. 0077 // 0078 // \return The signed distance from point to triangle. If negative, point is 0079 // inside the triangle. 0080 lowp float sdf_polygon(in lowp vec2 point, in lowp vec2[SDF_POLYGON_MAX_POINT_COUNT] vertices, in lowp int count) 0081 { 0082 lowp float d = dot(point - vertices[0], point - vertices[0]); 0083 lowp float s = 1.0; 0084 for (int i = 0, j = count - 1; i < count && i < SDF_POLYGON_MAX_POINT_COUNT; j = i, i++) 0085 { 0086 lowp vec2 e = vertices[j] - vertices[i]; 0087 lowp vec2 w = point - vertices[i]; 0088 lowp float h = clamp( dot(w, e) / dot(e, e), 0.0, 1.0 ); 0089 lowp vec2 b = w - e * h; 0090 d = min(d, dot(b, b)); 0091 0092 bvec3 c = bvec3(point.y >= vertices[i].y, point.y < vertices[j].y, e.x * w.y > e.y * w.x); 0093 if(all(c) || all(not(c))) s *= -1.0; 0094 } 0095 return s * sqrt(d); 0096 } 0097 #endif 0098 0099 // Distance field for a rectangle. 0100 // 0101 // \param point A point on the distance field. 0102 // \param rect A vec2 with the size of the rectangle. 0103 // 0104 // \return The signed distance from point to rectangle. If negative, point is 0105 // inside the rectangle. 0106 lowp float sdf_rectangle(in lowp vec2 point, in lowp vec2 rect) 0107 { 0108 lowp vec2 d = abs(point) - rect; 0109 return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); 0110 } 0111 0112 // Distance field for a torus segment. 0113 // 0114 // \param point A point on the distance field. 0115 // \param start The start angle in radians of the segment. 0116 // \param end The end angle in radians of the segment. 0117 // \param inner_radius The inner radius of the torus. 0118 // \param outer_radius The outer radius of the torus. 0119 // 0120 // \return The signed distance from point to the torus segment. If negative, 0121 // point is inside the segment. 0122 lowp float sdf_torus_segment(in lowp vec2 point, in lowp float start, in lowp float end, in lowp float inner_radius, in lowp float outer_radius) 0123 { 0124 start = clamp(start, end - 2.0 * pi, end); 0125 end = clamp(end, start, start + 2.0 * pi); 0126 0127 lowp float angle = (end - start) / 2.0; 0128 lowp float rotation = (start + end) / 2.0; 0129 0130 lowp vec2 rotated = point * mat2(cos(rotation), -sin(rotation), sin(rotation), cos(rotation)); 0131 lowp vec2 c = vec2(sin(angle), cos(angle)); 0132 0133 rotated.x = abs(rotated.x); 0134 0135 lowp float t = (outer_radius - inner_radius) / 2.0; 0136 lowp float l = abs(length(rotated) - (inner_radius + t)) - t; 0137 0138 lowp float m = length(rotated - c * clamp(dot(rotated, c), inner_radius, outer_radius)); 0139 return max(l, m * sign(c.y * rotated.x - c.x * rotated.y)); 0140 } 0141 0142 /********************* 0143 Operators 0144 *********************/ 0145 0146 // Convert a distance field to an annular (hollow) distance field. 0147 // 0148 // \param sdf The result of an sdf shape to convert. 0149 // \param thickness The thickness of the resulting shape. 0150 // 0151 // \return The value of sdf modified to an annular shape. 0152 lowp float sdf_annular(in lowp float sdf, in lowp float thickness) 0153 { 0154 return abs(sdf) - thickness; 0155 } 0156 0157 // Union two sdf shapes together. 0158 // 0159 // \param sdf1 The first sdf shape. 0160 // \param sdf2 The second sdf shape. 0161 // 0162 // \return The union of sdf1 and sdf2, that is, the distance to both sdf1 and 0163 // sdf2. 0164 lowp float sdf_union(in lowp float sdf1, in lowp float sdf2) 0165 { 0166 return min(sdf1, sdf2); 0167 } 0168 0169 // Subtract two sdf shapes. 0170 // 0171 // \param sdf1 The first sdf shape. 0172 // \param sdf2 The second sdf shape. 0173 // 0174 // \return sdf1 with sdf2 subtracted from it. 0175 lowp float sdf_subtract(in lowp float sdf1, in lowp float sdf2) 0176 { 0177 return max(sdf1, -sdf2); 0178 } 0179 0180 // Intersect two sdf shapes. 0181 // 0182 // \param sdf1 The first sdf shape. 0183 // \param sdf2 The second sdf shape. 0184 // 0185 // \return The intersection between sdf1 and sdf2, that is, the area where both 0186 // sdf1 and sdf2 provide the same distance value. 0187 lowp float sdf_intersect(in lowp float sdf1, in lowp float sdf2) 0188 { 0189 return max(sdf1, sdf2); 0190 } 0191 0192 // Smoothly intersect two sdf shapes. 0193 // 0194 // \param sdf1 The first sdf shape. 0195 // \param sdf2 The second sdf shape. 0196 // \param smoothing The amount of smoothing to apply. 0197 // 0198 // \return A smoothed version of the intersect operation. 0199 lowp float sdf_intersect_smooth(in lowp float sdf1, in lowp float sdf2, in lowp float smoothing) 0200 { 0201 lowp float h = clamp(0.5 - 0.5 * (sdf1 - sdf2) / smoothing, 0.0, 1.0); 0202 return mix(sdf1, sdf2, h) + smoothing * h * (1.0 - h); 0203 } 0204 0205 // Round an sdf shape. 0206 // 0207 // \param sdf The sdf shape to round. 0208 // \param amount The amount of rounding to apply. 0209 // 0210 // \return The rounded shape of sdf. 0211 // Note that rounding happens by basically selecting an isoline of sdf, 0212 // therefore, the resulting shape may be larger than the input shape. 0213 lowp float sdf_round(in lowp float sdf, in lowp float amount) 0214 { 0215 return sdf - amount; 0216 } 0217 0218 // Convert an sdf shape to an outline of its shape. 0219 // 0220 // \param sdf The sdf shape to turn into an outline. 0221 // 0222 // \return The outline of sdf. 0223 lowp float sdf_outline(in lowp float sdf) 0224 { 0225 return abs(sdf); 0226 } 0227 0228 /******************** 0229 Convenience 0230 ********************/ 0231 0232 // A constant to represent a "null" value of an sdf. 0233 // Since 0 is a point exactly on the outline of an sdf shape, and negative 0234 // values are inside the shape, this uses a very large positive constant to 0235 // indicate a value that is really far away from the actual sdf shape. 0236 const lowp float sdf_null = 99999.0; 0237 0238 // A constant for a default level of smoothing when rendering an sdf. 0239 const lowp float sdf_default_smoothing = 0.625; 0240 0241 // Render an sdf shape. 0242 // 0243 // This will render the sdf shape on top of whatever source color is input, 0244 // making sure to apply smoothing if desired. 0245 // 0246 // \param sdf The sdf shape to render. 0247 // \param sourceColor The source color to render on top of. 0248 // \param sdfColor The color to use for rendering the sdf shape. 0249 // 0250 // \return sourceColor with the sdf shape rendered on top. 0251 lowp vec4 sdf_render(in lowp float sdf, in lowp vec4 sourceColor, in lowp vec4 sdfColor) 0252 { 0253 lowp float g = fwidth(sdf); 0254 return mix(sourceColor, sdfColor, 1.0 - smoothstep(-sdf_default_smoothing * g, sdf_default_smoothing * g, sdf)); 0255 } 0256 0257 // Render an sdf shape. 0258 // 0259 // This is an overload of sdf_render(float, vec4, vec4) that allows specifying a 0260 // smoothing amount. 0261 // 0262 // \param smoothing The amount of smoothing to apply to the sdf. 0263 // 0264 lowp vec4 sdf_render(in lowp float sdf, in lowp vec4 sourceColor, in lowp vec4 sdfColor, in lowp float smoothing) 0265 { 0266 lowp float g = fwidth(sdf); 0267 return mix(sourceColor, sdfColor, 1.0 - smoothstep(-smoothing * g, smoothing * g, sdf)); 0268 } 0269 0270 // Render an sdf shape alpha-blended onto an existing color. 0271 // 0272 // This is an overload of sdf_render(float, vec4, vec4) that allows specifying a 0273 // blending amount and a smoothing amount. 0274 // 0275 // \param alpha The alpha to use for blending. 0276 // \param smoothing The amount of smoothing to apply to the sdf. 0277 // 0278 lowp vec4 sdf_render(in lowp float sdf, in lowp vec4 sourceColor, in lowp vec4 sdfColor, in lowp float alpha, in lowp float smoothing) 0279 { 0280 lowp float g = fwidth(sdf); 0281 return mix(sourceColor, sdfColor, alpha * (1.0 - smoothstep(-smoothing * g, smoothing * g, sdf))); 0282 }