Added backdrop effects pipeline (blur)
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct Uniforms
|
||||
{
|
||||
float2 inv_working_size;
|
||||
uint pair_count;
|
||||
uint mode;
|
||||
float2 direction;
|
||||
float inv_downsample_factor;
|
||||
float _pad0;
|
||||
float4 kernel0[32];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 out_color [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float2 p_local [[user(locn0)]];
|
||||
float4 f_color [[user(locn1)]];
|
||||
float2 f_half_size [[user(locn2), flat]];
|
||||
float4 f_radii [[user(locn3), flat]];
|
||||
float f_half_feather [[user(locn4), flat]];
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
float3 blur_sample(thread const float2& uv, constant Uniforms& _108, texture2d<float> blur_input_tex, sampler blur_input_texSmplr)
|
||||
{
|
||||
float3 color = blur_input_tex.sample(blur_input_texSmplr, uv).xyz * _108.kernel0[0].x;
|
||||
float2 axis_step = _108.direction * _108.inv_working_size;
|
||||
for (uint i = 1u; i < _108.pair_count; i++)
|
||||
{
|
||||
float w = _108.kernel0[i].x;
|
||||
float off = _108.kernel0[i].y;
|
||||
float2 step_uv = axis_step * off;
|
||||
color += (blur_input_tex.sample(blur_input_texSmplr, (uv - step_uv)).xyz * w);
|
||||
color += (blur_input_tex.sample(blur_input_texSmplr, (uv + step_uv)).xyz * w);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
float sdRoundedBox(thread const float2& p, thread const float2& b, thread const float4& r)
|
||||
{
|
||||
float2 _36;
|
||||
if (p.x > 0.0)
|
||||
{
|
||||
_36 = r.xy;
|
||||
}
|
||||
else
|
||||
{
|
||||
_36 = r.zw;
|
||||
}
|
||||
float2 rxy = _36;
|
||||
float _50;
|
||||
if (p.y > 0.0)
|
||||
{
|
||||
_50 = rxy.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_50 = rxy.y;
|
||||
}
|
||||
float rr = _50;
|
||||
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 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]], constant Uniforms& _108 [[buffer(0)]], texture2d<float> blur_input_tex [[texture(0)]], sampler blur_input_texSmplr [[sampler(0)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
if (_108.mode == 0u)
|
||||
{
|
||||
float2 uv = gl_FragCoord.xy * _108.inv_working_size;
|
||||
float2 param = uv;
|
||||
float3 color = blur_sample(param, _108, blur_input_tex, blur_input_texSmplr);
|
||||
out.out_color = float4(color, 1.0);
|
||||
return out;
|
||||
}
|
||||
float2 param_1 = in.p_local;
|
||||
float2 param_2 = in.f_half_size;
|
||||
float4 param_3 = in.f_radii;
|
||||
float d = sdRoundedBox(param_1, param_2, param_3);
|
||||
if (d > in.f_half_feather)
|
||||
{
|
||||
discard_fragment();
|
||||
}
|
||||
float grad_magnitude = fast::max(fwidth(d), 9.9999999747524270787835121154785e-07);
|
||||
float d_n = d / grad_magnitude;
|
||||
float h_n = in.f_half_feather / grad_magnitude;
|
||||
float2 uv_1 = (gl_FragCoord.xy * _108.inv_downsample_factor) * _108.inv_working_size;
|
||||
float3 color_1 = blur_input_tex.sample(blur_input_texSmplr, uv_1).xyz;
|
||||
float3 tinted = mix(color_1, color_1 * in.f_color.xyz, float3(in.f_color.w));
|
||||
float param_4 = d_n;
|
||||
float param_5 = h_n;
|
||||
float coverage = sdf_alpha(param_4, param_5);
|
||||
out.out_color = float4(tinted * coverage, coverage);
|
||||
return out;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,123 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
template<typename T, size_t Num>
|
||||
struct spvUnsafeArray
|
||||
{
|
||||
T elements[Num ? Num : 1];
|
||||
|
||||
thread T& operator [] (size_t pos) thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const thread T& operator [] (size_t pos) const thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
device T& operator [] (size_t pos) device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const device T& operator [] (size_t pos) const device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
constexpr const constant T& operator [] (size_t pos) const constant
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
threadgroup T& operator [] (size_t pos) threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
};
|
||||
|
||||
struct Uniforms
|
||||
{
|
||||
float4x4 projection;
|
||||
float dpi_scale;
|
||||
uint mode;
|
||||
float2 _pad0;
|
||||
};
|
||||
|
||||
struct Backdrop_Primitive
|
||||
{
|
||||
float4 bounds;
|
||||
float4 radii;
|
||||
float2 half_size;
|
||||
float half_feather;
|
||||
uint color;
|
||||
};
|
||||
|
||||
struct Backdrop_Primitive_1
|
||||
{
|
||||
float4 bounds;
|
||||
float4 radii;
|
||||
float2 half_size;
|
||||
float half_feather;
|
||||
uint color;
|
||||
};
|
||||
|
||||
struct Backdrop_Primitives
|
||||
{
|
||||
Backdrop_Primitive_1 primitives[1];
|
||||
};
|
||||
|
||||
constant spvUnsafeArray<float2, 6> _97 = spvUnsafeArray<float2, 6>({ float2(0.0), float2(1.0, 0.0), float2(0.0, 1.0), float2(0.0, 1.0), float2(1.0, 0.0), float2(1.0) });
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 p_local [[user(locn0)]];
|
||||
float4 f_color [[user(locn1)]];
|
||||
float2 f_half_size [[user(locn2)]];
|
||||
float4 f_radii [[user(locn3)]];
|
||||
float f_half_feather [[user(locn4)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(constant Uniforms& _13 [[buffer(0)]], const device Backdrop_Primitives& _69 [[buffer(1)]], uint gl_VertexIndex [[vertex_id]], uint gl_InstanceIndex [[instance_id]])
|
||||
{
|
||||
main0_out out = {};
|
||||
if (_13.mode == 0u)
|
||||
{
|
||||
float2 ndc = float2((int(gl_VertexIndex) == 1) ? 3.0 : (-1.0), (int(gl_VertexIndex) == 2) ? 3.0 : (-1.0));
|
||||
out.gl_Position = float4(ndc, 0.0, 1.0);
|
||||
out.p_local = float2(0.0);
|
||||
out.f_color = float4(0.0);
|
||||
out.f_half_size = float2(0.0);
|
||||
out.f_radii = float4(0.0);
|
||||
out.f_half_feather = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Backdrop_Primitive p;
|
||||
p.bounds = _69.primitives[int(gl_InstanceIndex)].bounds;
|
||||
p.radii = _69.primitives[int(gl_InstanceIndex)].radii;
|
||||
p.half_size = _69.primitives[int(gl_InstanceIndex)].half_size;
|
||||
p.half_feather = _69.primitives[int(gl_InstanceIndex)].half_feather;
|
||||
p.color = _69.primitives[int(gl_InstanceIndex)].color;
|
||||
float2 corner = _97[int(gl_VertexIndex)];
|
||||
float2 world_pos = mix(p.bounds.xy, p.bounds.zw, corner);
|
||||
float2 center = (p.bounds.xy + p.bounds.zw) * 0.5;
|
||||
out.p_local = (world_pos - center) * _13.dpi_scale;
|
||||
out.f_color = unpack_unorm4x8_to_float(p.color);
|
||||
out.f_half_size = p.half_size;
|
||||
out.f_radii = p.radii;
|
||||
out.f_half_feather = p.half_feather;
|
||||
out.gl_Position = _13.projection * float4(world_pos * _13.dpi_scale, 0.0, 1.0);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct Uniforms
|
||||
{
|
||||
float2 inv_source_size;
|
||||
uint downsample_factor;
|
||||
uint _pad0;
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 out_color [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(constant Uniforms& _18 [[buffer(0)]], texture2d<float> source_tex [[texture(0)]], sampler source_texSmplr [[sampler(0)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float2 src_block_center = gl_FragCoord.xy * float(_18.downsample_factor);
|
||||
if (_18.downsample_factor == 1u)
|
||||
{
|
||||
float2 uv = src_block_center * _18.inv_source_size;
|
||||
out.out_color = source_tex.sample(source_texSmplr, uv);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_18.downsample_factor == 2u)
|
||||
{
|
||||
float2 uv_1 = src_block_center * _18.inv_source_size;
|
||||
out.out_color = source_tex.sample(source_texSmplr, uv_1);
|
||||
}
|
||||
else
|
||||
{
|
||||
float off = float(_18.downsample_factor) * 0.25;
|
||||
float2 uv_tl = (src_block_center + float2(-off, -off)) * _18.inv_source_size;
|
||||
float2 uv_tr = (src_block_center + float2(off, -off)) * _18.inv_source_size;
|
||||
float2 uv_bl = (src_block_center + float2(-off, off)) * _18.inv_source_size;
|
||||
float2 uv_br = (src_block_center + float2(off)) * _18.inv_source_size;
|
||||
float4 c = ((source_tex.sample(source_texSmplr, uv_tl) + source_tex.sample(source_texSmplr, uv_tr)) + source_tex.sample(source_texSmplr, uv_bl)) + source_tex.sample(source_texSmplr, uv_br);
|
||||
out.out_color = c * 0.25;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(uint gl_VertexIndex [[vertex_id]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float2 ndc = float2((int(gl_VertexIndex) == 1) ? 3.0 : (-1.0), (int(gl_VertexIndex) == 2) ? 3.0 : (-1.0));
|
||||
out.gl_Position = float4(ndc, 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -24,8 +24,8 @@ struct main0_in
|
||||
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)]];
|
||||
float4 f_uv_rect [[user(locn6), flat]];
|
||||
uint4 f_effects [[user(locn7)]];
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
@@ -109,11 +109,6 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
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<half2>(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);
|
||||
@@ -163,16 +158,16 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
{
|
||||
float d_start = dot(p_local, n_start);
|
||||
float d_end = dot(p_local, n_end);
|
||||
float _372;
|
||||
float _338;
|
||||
if (arc_bits == 1u)
|
||||
{
|
||||
_372 = fast::max(d_start, d_end);
|
||||
_338 = fast::max(d_start, d_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
_372 = fast::min(d_start, d_end);
|
||||
_338 = fast::min(d_start, d_end);
|
||||
}
|
||||
float d_wedge = _372;
|
||||
float d_wedge = _338;
|
||||
d = fast::max(d, d_wedge);
|
||||
}
|
||||
half_size = float2(outer);
|
||||
@@ -187,7 +182,7 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
if ((flags & 2u) != 0u)
|
||||
{
|
||||
float4 gradient_start = in.f_color;
|
||||
float4 gradient_end = unpack_unorm4x8_to_float(in.f_uv_or_effects.x);
|
||||
float4 gradient_end = unpack_unorm4x8_to_float(in.f_effects.x);
|
||||
if ((flags & 4u) != 0u)
|
||||
{
|
||||
float t_1 = length(p_local / half_size);
|
||||
@@ -198,7 +193,7 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
}
|
||||
else
|
||||
{
|
||||
float2 direction = float2(as_type<half2>(in.f_uv_or_effects.z));
|
||||
float2 direction = float2(as_type<half2>(in.f_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;
|
||||
@@ -210,7 +205,7 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
{
|
||||
if ((flags & 1u) != 0u)
|
||||
{
|
||||
float4 uv_rect = as_type<float4>(in.f_uv_or_effects);
|
||||
float4 uv_rect = in.f_uv_rect;
|
||||
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);
|
||||
@@ -222,8 +217,8 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
}
|
||||
if ((flags & 8u) != 0u)
|
||||
{
|
||||
float4 ol_color = unpack_unorm4x8_to_float(in.f_uv_or_effects.y);
|
||||
float ol_width = float2(as_type<half2>(in.f_uv_or_effects.w)).x / grad_magnitude;
|
||||
float4 ol_color = unpack_unorm4x8_to_float(in.f_effects.y);
|
||||
float ol_width = float2(as_type<half2>(in.f_effects.w)).x / grad_magnitude;
|
||||
float param_14 = d;
|
||||
float param_15 = h;
|
||||
float fill_cov = sdf_alpha(param_14, param_15);
|
||||
|
||||
Binary file not shown.
@@ -10,7 +10,7 @@ struct Uniforms
|
||||
uint mode;
|
||||
};
|
||||
|
||||
struct Primitive
|
||||
struct Base_2D_Primitive
|
||||
{
|
||||
float4 bounds;
|
||||
uint color;
|
||||
@@ -19,10 +19,11 @@ struct Primitive
|
||||
float _pad;
|
||||
float4 params;
|
||||
float4 params2;
|
||||
uint4 uv_or_effects;
|
||||
float4 uv_rect;
|
||||
uint4 effects;
|
||||
};
|
||||
|
||||
struct Primitive_1
|
||||
struct Base_2D_Primitive_1
|
||||
{
|
||||
float4 bounds;
|
||||
uint color;
|
||||
@@ -31,12 +32,13 @@ struct Primitive_1
|
||||
float _pad;
|
||||
float4 params;
|
||||
float4 params2;
|
||||
uint4 uv_or_effects;
|
||||
float4 uv_rect;
|
||||
uint4 effects;
|
||||
};
|
||||
|
||||
struct Primitives
|
||||
struct Base_2D_Primitives
|
||||
{
|
||||
Primitive_1 primitives[1];
|
||||
Base_2D_Primitive_1 primitives[1];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
@@ -46,8 +48,8 @@ struct main0_out
|
||||
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)]];
|
||||
float4 f_uv_rect [[user(locn6)]];
|
||||
uint4 f_effects [[user(locn7)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
@@ -58,7 +60,7 @@ struct main0_in
|
||||
float4 v_color [[attribute(2)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant Uniforms& _12 [[buffer(0)]], const device Primitives& _75 [[buffer(1)]], uint gl_InstanceIndex [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant Uniforms& _12 [[buffer(0)]], const device Base_2D_Primitives& _75 [[buffer(1)]], uint gl_InstanceIndex [[instance_id]])
|
||||
{
|
||||
main0_out out = {};
|
||||
if (_12.mode == 0u)
|
||||
@@ -68,13 +70,13 @@ vertex main0_out main0(main0_in in [[stage_in]], constant Uniforms& _12 [[buffer
|
||||
out.f_params = float4(0.0);
|
||||
out.f_params2 = float4(0.0);
|
||||
out.f_flags = 0u;
|
||||
out.f_rotation_sc = 0u;
|
||||
out.f_uv_or_effects = uint4(0u);
|
||||
out.f_uv_rect = float4(0.0);
|
||||
out.f_effects = uint4(0u);
|
||||
out.gl_Position = _12.projection * float4(in.v_position * _12.dpi_scale, 0.0, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Primitive p;
|
||||
Base_2D_Primitive p;
|
||||
p.bounds = _75.primitives[int(gl_InstanceIndex)].bounds;
|
||||
p.color = _75.primitives[int(gl_InstanceIndex)].color;
|
||||
p.flags = _75.primitives[int(gl_InstanceIndex)].flags;
|
||||
@@ -82,17 +84,25 @@ vertex main0_out main0(main0_in in [[stage_in]], constant Uniforms& _12 [[buffer
|
||||
p._pad = _75.primitives[int(gl_InstanceIndex)]._pad;
|
||||
p.params = _75.primitives[int(gl_InstanceIndex)].params;
|
||||
p.params2 = _75.primitives[int(gl_InstanceIndex)].params2;
|
||||
p.uv_or_effects = _75.primitives[int(gl_InstanceIndex)].uv_or_effects;
|
||||
p.uv_rect = _75.primitives[int(gl_InstanceIndex)].uv_rect;
|
||||
p.effects = _75.primitives[int(gl_InstanceIndex)].effects;
|
||||
float2 corner = in.v_position;
|
||||
float2 world_pos = mix(p.bounds.xy, p.bounds.zw, corner);
|
||||
float2 center = (p.bounds.xy + p.bounds.zw) * 0.5;
|
||||
float2 local = (world_pos - center) * _12.dpi_scale;
|
||||
uint flags = (p.flags >> 8u) & 255u;
|
||||
if ((flags & 16u) != 0u)
|
||||
{
|
||||
float2 sc = float2(as_type<half2>(p.rotation_sc));
|
||||
local = float2((sc.y * local.x) + (sc.x * local.y), ((-sc.x) * local.x) + (sc.y * local.y));
|
||||
}
|
||||
out.f_color = unpack_unorm4x8_to_float(p.color);
|
||||
out.f_local_or_uv = (world_pos - center) * _12.dpi_scale;
|
||||
out.f_local_or_uv = local;
|
||||
out.f_params = p.params;
|
||||
out.f_params2 = p.params2;
|
||||
out.f_flags = p.flags;
|
||||
out.f_rotation_sc = p.rotation_sc;
|
||||
out.f_uv_or_effects = p.uv_or_effects;
|
||||
out.f_uv_rect = p.uv_rect;
|
||||
out.f_effects = p.effects;
|
||||
out.gl_Position = _12.projection * float4(world_pos * _12.dpi_scale, 0.0, 1.0);
|
||||
}
|
||||
return out;
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user