#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_flags [[user(locn4)]]; uint f_rotation_sc [[user(locn5)]]; uint4 f_uv_or_effects [[user(locn6)]]; }; static inline __attribute__((always_inline)) float sdRoundedBox(thread const float2& p, thread const float2& b, thread const float4& r) { float2 _48; if (p.x > 0.0) { _48 = r.xy; } else { _48 = r.zw; } float2 rxy = _48; float _62; if (p.y > 0.0) { _62 = rxy.x; } else { _62 = rxy.y; } float rr = _62; float2 q = abs(p) - b; if (rr == 0.0) { return fast::max(q.x, q.y); } q += float2(rr); return (fast::min(fast::max(q.x, q.y), 0.0) + length(fast::max(q, float2(0.0)))) - rr; } static inline __attribute__((always_inline)) float sdRegularPolygon(thread const float2& p, thread const float& r, thread const float& n) { float an = 3.1415927410125732421875 / n; float bn = mod(precise::atan2(p.y, p.x), 2.0 * an) - an; return (length(p) * cos(bn)) - r; } static inline __attribute__((always_inline)) float sdEllipseApprox(thread const float2& p, thread const float2& ab) { float k0 = length(p / ab); float k1 = length(p / (ab * ab)); return (k0 * (k0 - 1.0)) / k1; } static inline __attribute__((always_inline)) float4 gradient_2color(thread const float4& start_color, thread const float4& end_color, thread const float& t) { return mix(start_color, end_color, float4(fast::clamp(t, 0.0, 1.0))); } static inline __attribute__((always_inline)) float sdf_alpha(thread const float& d, thread const float& h) { return 1.0 - smoothstep(-h, h, 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_flags & 255u; uint flags = (in.f_flags >> 8u) & 255u; if (kind == 0u) { float4 t = tex.sample(texSmplr, in.f_local_or_uv); float _195 = t.w; float4 _197 = t; float3 _199 = _197.xyz * _195; t.x = _199.x; t.y = _199.y; t.z = _199.z; out.out_color = in.f_color * t; return out; } float d = 1000000015047466219876688855040.0; float h = 0.5; float2 half_size = in.f_params.xy; float2 p_local = in.f_local_or_uv; if ((flags & 16u) != 0u) { float2 sc = float2(as_type(in.f_rotation_sc)); p_local = float2((sc.y * p_local.x) + (sc.x * p_local.y), ((-sc.x) * p_local.x) + (sc.y * p_local.y)); } if (kind == 1u) { float4 corner_radii = float4(in.f_params.zw, in.f_params2.xy); h = in.f_params2.z; float2 param = p_local; float2 param_1 = half_size; float4 param_2 = corner_radii; d = sdRoundedBox(param, param_1, param_2); } else { if (kind == 2u) { float radius = in.f_params.x; float sides = in.f_params.y; h = in.f_params.z; float2 param_3 = p_local; float param_4 = radius; float param_5 = sides; d = sdRegularPolygon(param_3, param_4, param_5); half_size = float2(radius); } else { if (kind == 3u) { float2 ab = in.f_params.xy; h = in.f_params.z; float2 param_6 = p_local; float2 param_7 = ab; d = sdEllipseApprox(param_6, param_7); half_size = ab; } else { if (kind == 4u) { float inner = in.f_params.x; float outer = in.f_params.y; float2 n_start = in.f_params.zw; float2 n_end = in.f_params2.xy; uint arc_bits = (flags >> 5u) & 3u; h = in.f_params2.z; float r = length(p_local); d = fast::max(inner - r, r - outer); if (arc_bits != 0u) { float d_start = dot(p_local, n_start); float d_end = dot(p_local, n_end); float _372; if (arc_bits == 1u) { _372 = fast::max(d_start, d_end); } else { _372 = fast::min(d_start, d_end); } float d_wedge = _372; d = fast::max(d, d_wedge); } half_size = float2(outer); } } } } float grad_magnitude = fast::max(fwidth(d), 9.9999999747524270787835121154785e-07); d /= grad_magnitude; h /= grad_magnitude; float4 shape_color; if ((flags & 2u) != 0u) { float4 gradient_start = in.f_color; float4 gradient_end = unpack_unorm4x8_to_float(in.f_uv_or_effects.x); if ((flags & 4u) != 0u) { float t_1 = length(p_local / half_size); float4 param_8 = gradient_start; float4 param_9 = gradient_end; float param_10 = t_1; shape_color = gradient_2color(param_8, param_9, param_10); } else { float2 direction = float2(as_type(in.f_uv_or_effects.z)); float t_2 = (dot(p_local / half_size, direction) * 0.5) + 0.5; float4 param_11 = gradient_start; float4 param_12 = gradient_end; float param_13 = t_2; shape_color = gradient_2color(param_11, param_12, param_13); } } else { if ((flags & 1u) != 0u) { float4 uv_rect = as_type(in.f_uv_or_effects); float2 local_uv = ((p_local / half_size) * 0.5) + float2(0.5); float2 uv = mix(uv_rect.xy, uv_rect.zw, local_uv); shape_color = in.f_color * tex.sample(texSmplr, uv); } else { shape_color = in.f_color; } } if ((flags & 8u) != 0u) { float4 ol_color = unpack_unorm4x8_to_float(in.f_uv_or_effects.y); float ol_width = float2(as_type(in.f_uv_or_effects.w)).x / grad_magnitude; float param_14 = d; float param_15 = h; float fill_cov = sdf_alpha(param_14, param_15); float param_16 = d - ol_width; float param_17 = h; float total_cov = sdf_alpha(param_16, param_17); float outline_cov = fast::max(total_cov - fill_cov, 0.0); float3 rgb_pm = ((shape_color.xyz * shape_color.w) * fill_cov) + ((ol_color.xyz * ol_color.w) * outline_cov); float alpha_pm = (shape_color.w * fill_cov) + (ol_color.w * outline_cov); out.out_color = float4(rgb_pm, alpha_pm); } else { float param_18 = d; float param_19 = h; float alpha = sdf_alpha(param_18, param_19); out.out_color = float4((shape_color.xyz * shape_color.w) * alpha, shape_color.w * alpha); } return out; }