#pragma clang diagnostic ignored "-Wmissing-prototypes" #include #include using namespace metal; // Implementation of the GLSL mod() function, which is slightly different than Metal fmod() template inline Tx mod(Tx x, Ty y) { return x - y * floor(x / y); } struct main0_out { float4 out_color [[color(0)]]; }; struct main0_in { float4 f_color [[user(locn0)]]; float2 f_local_or_uv [[user(locn1)]]; float4 f_params [[user(locn2)]]; float4 f_params2 [[user(locn3)]]; uint f_kind_flags [[user(locn4)]]; }; static inline __attribute__((always_inline)) float sdRoundedBox(thread const float2& p, thread const float2& b, thread float4& r) { float2 _56; if (p.x > 0.0) { _56 = r.xy; } else { _56 = r.zw; } r.x = _56.x; r.y = _56.y; float _73; if (p.y > 0.0) { _73 = r.x; } else { _73 = r.y; } r.x = _73; float2 q = (abs(p) - b) + float2(r.x); return (fast::min(fast::max(q.x, q.y), 0.0) + length(fast::max(q, float2(0.0)))) - r.x; } static inline __attribute__((always_inline)) float sdf_stroke(thread const float& d, thread const float& stroke_width) { return abs(d) - (stroke_width * 0.5); } static inline __attribute__((always_inline)) float sdCircle(thread const float2& p, thread const float& r) { return length(p) - r; } static inline __attribute__((always_inline)) float sdEllipse(thread float2& p, thread float2& ab) { p = abs(p); if (p.x > p.y) { p = p.yx; ab = ab.yx; } float l = (ab.y * ab.y) - (ab.x * ab.x); float m = (ab.x * p.x) / l; float m2 = m * m; float n = (ab.y * p.y) / l; float n2 = n * n; float c = ((m2 + n2) - 1.0) / 3.0; float c3 = (c * c) * c; float q = c3 + ((m2 * n2) * 2.0); float d = c3 + (m2 * n2); float g = m + (m * n2); float co; if (d < 0.0) { float h = acos(q / c3) / 3.0; float s = cos(h); float t = sin(h) * 1.73205077648162841796875; float rx = sqrt(((-c) * ((s + t) + 2.0)) + m2); float ry = sqrt(((-c) * ((s - t) + 2.0)) + m2); co = (((ry + (sign(l) * rx)) + (abs(g) / (rx * ry))) - m) / 2.0; } else { float h_1 = ((2.0 * m) * n) * sqrt(d); float s_1 = sign(q + h_1) * powr(abs(q + h_1), 0.3333333432674407958984375); float u = sign(q - h_1) * powr(abs(q - h_1), 0.3333333432674407958984375); float rx_1 = (((-s_1) - u) - (c * 4.0)) + (2.0 * m2); float ry_1 = (s_1 - u) * 1.73205077648162841796875; float rm = sqrt((rx_1 * rx_1) + (ry_1 * ry_1)); co = (((ry_1 / sqrt(rm - rx_1)) + ((2.0 * g) / rm)) - m) / 2.0; } float2 r = ab * float2(co, sqrt(1.0 - (co * co))); return length(r - p) * sign(p.y - r.y); } static inline __attribute__((always_inline)) float sdSegment(thread const float2& p, thread const float2& a, thread const float2& b) { float2 pa = p - a; float2 ba = b - a; float h = fast::clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); return length(pa - (ba * h)); } static inline __attribute__((always_inline)) float sdf_alpha(thread const float& d, thread const float& soft) { return 1.0 - smoothstep(-soft, soft, d); } fragment main0_out main0(main0_in in [[stage_in]], texture2d tex [[texture(0)]], sampler texSmplr [[sampler(0)]]) { main0_out out = {}; uint kind = in.f_kind_flags & 255u; uint flags = (in.f_kind_flags >> 8u) & 255u; if (kind == 0u) { out.out_color = in.f_color * tex.sample(texSmplr, in.f_local_or_uv); return out; } float d = 1000000015047466219876688855040.0; float soft = 1.0; if (kind == 1u) { float2 b = in.f_params.xy; float4 r = float4(in.f_params.zw, in.f_params2.xy); soft = fast::max(in.f_params2.z, 1.0); float stroke_px = in.f_params2.w; float2 param = in.f_local_or_uv; float2 param_1 = b; float4 param_2 = r; float _453 = sdRoundedBox(param, param_1, param_2); d = _453; if ((flags & 1u) != 0u) { float param_3 = d; float param_4 = stroke_px; d = sdf_stroke(param_3, param_4); } } else { if (kind == 2u) { float radius = in.f_params.x; soft = fast::max(in.f_params.y, 1.0); float stroke_px_1 = in.f_params.z; float2 param_5 = in.f_local_or_uv; float param_6 = radius; d = sdCircle(param_5, param_6); if ((flags & 1u) != 0u) { float param_7 = d; float param_8 = stroke_px_1; d = sdf_stroke(param_7, param_8); } } else { if (kind == 3u) { float2 ab = in.f_params.xy; soft = fast::max(in.f_params.z, 1.0); float stroke_px_2 = in.f_params.w; float2 param_9 = in.f_local_or_uv; float2 param_10 = ab; float _511 = sdEllipse(param_9, param_10); d = _511; if ((flags & 1u) != 0u) { float param_11 = d; float param_12 = stroke_px_2; d = sdf_stroke(param_11, param_12); } } else { if (kind == 4u) { float2 a = in.f_params.xy; float2 b_1 = in.f_params.zw; float width = in.f_params2.x; soft = fast::max(in.f_params2.y, 1.0); float2 param_13 = in.f_local_or_uv; float2 param_14 = a; float2 param_15 = b_1; d = sdSegment(param_13, param_14, param_15) - (width * 0.5); } else { if (kind == 5u) { float inner = in.f_params.x; float outer = in.f_params.y; float start_rad = in.f_params.z; float end_rad = in.f_params.w; soft = fast::max(in.f_params2.x, 1.0); float r_1 = length(in.f_local_or_uv); float d_ring = fast::max(inner - r_1, r_1 - outer); float angle = precise::atan2(in.f_local_or_uv.y, in.f_local_or_uv.x); if (angle < 0.0) { angle += 6.283185482025146484375; } float ang_start = start_rad; float ang_end = end_rad; if (ang_start < 0.0) { ang_start += 6.283185482025146484375; } if (ang_end < 0.0) { ang_end += 6.283185482025146484375; } float _615; if (ang_end > ang_start) { _615 = float((angle >= ang_start) && (angle <= ang_end)); } else { _615 = float((angle >= ang_start) || (angle <= ang_end)); } float in_arc = _615; if (abs(ang_end - ang_start) >= 6.282185077667236328125) { in_arc = 1.0; } d = (in_arc > 0.5) ? d_ring : 1000000015047466219876688855040.0; } else { if (kind == 6u) { float radius_1 = in.f_params.x; float rotation = in.f_params.y; float sides = in.f_params.z; soft = fast::max(in.f_params.w, 1.0); float stroke_px_3 = in.f_params2.x; float2 p = in.f_local_or_uv; float c = cos(rotation); float s = sin(rotation); p = float2x2(float2(c, -s), float2(s, c)) * p; float an = 3.1415927410125732421875 / sides; float bn = mod(precise::atan2(p.y, p.x), 2.0 * an) - an; d = (length(p) * cos(bn)) - radius_1; if ((flags & 1u) != 0u) { float param_16 = d; float param_17 = stroke_px_3; d = sdf_stroke(param_16, param_17); } } } } } } } float param_18 = d; float param_19 = soft; float alpha = sdf_alpha(param_18, param_19); out.out_color = float4(in.f_color.xyz, in.f_color.w * alpha); return out; }