Texture Rendering (#9)
Co-authored-by: Zachary Levy <zachary@sunforge.is> Reviewed-on: #9
This commit was merged in pull request #9.
This commit is contained in:
@@ -25,6 +25,7 @@ struct main0_in
|
||||
float4 f_params2 [[user(locn3)]];
|
||||
uint f_kind_flags [[user(locn4)]];
|
||||
float f_rotation [[user(locn5), flat]];
|
||||
float4 f_uv_rect [[user(locn6), flat]];
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
@@ -69,6 +70,12 @@ 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 sdf_alpha(thread const float& d, thread const float& soft)
|
||||
{
|
||||
return 1.0 - smoothstep(-soft, soft, d);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
float sdCircle(thread const float2& p, thread const float& r)
|
||||
{
|
||||
@@ -127,12 +134,6 @@ float sdSegment(thread const float2& p, thread const float2& a, thread const flo
|
||||
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<float> tex [[texture(0)]], sampler texSmplr [[sampler(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
@@ -169,6 +170,25 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
float param_6 = stroke_px;
|
||||
d = sdf_stroke(param_5, param_6);
|
||||
}
|
||||
float4 shape_color = in.f_color;
|
||||
if ((flags & 2u) != 0u)
|
||||
{
|
||||
float2 p_for_uv = in.f_local_or_uv;
|
||||
if (in.f_rotation != 0.0)
|
||||
{
|
||||
float2 param_7 = p_for_uv;
|
||||
float param_8 = in.f_rotation;
|
||||
p_for_uv = apply_rotation(param_7, param_8);
|
||||
}
|
||||
float2 local_uv = ((p_for_uv / b) * 0.5) + float2(0.5);
|
||||
float2 uv = mix(in.f_uv_rect.xy, in.f_uv_rect.zw, local_uv);
|
||||
shape_color *= tex.sample(texSmplr, uv);
|
||||
}
|
||||
float param_9 = d;
|
||||
float param_10 = soft;
|
||||
float alpha = sdf_alpha(param_9, param_10);
|
||||
out.out_color = float4(shape_color.xyz, shape_color.w * alpha);
|
||||
return out;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -177,14 +197,14 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
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_7 = in.f_local_or_uv;
|
||||
float param_8 = radius;
|
||||
d = sdCircle(param_7, param_8);
|
||||
float2 param_11 = in.f_local_or_uv;
|
||||
float param_12 = radius;
|
||||
d = sdCircle(param_11, param_12);
|
||||
if ((flags & 1u) != 0u)
|
||||
{
|
||||
float param_9 = d;
|
||||
float param_10 = stroke_px_1;
|
||||
d = sdf_stroke(param_9, param_10);
|
||||
float param_13 = d;
|
||||
float param_14 = stroke_px_1;
|
||||
d = sdf_stroke(param_13, param_14);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -197,19 +217,19 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
float2 p_local_1 = in.f_local_or_uv;
|
||||
if (in.f_rotation != 0.0)
|
||||
{
|
||||
float2 param_11 = p_local_1;
|
||||
float param_12 = in.f_rotation;
|
||||
p_local_1 = apply_rotation(param_11, param_12);
|
||||
float2 param_15 = p_local_1;
|
||||
float param_16 = in.f_rotation;
|
||||
p_local_1 = apply_rotation(param_15, param_16);
|
||||
}
|
||||
float2 param_13 = p_local_1;
|
||||
float2 param_14 = ab;
|
||||
float _560 = sdEllipse(param_13, param_14);
|
||||
d = _560;
|
||||
float2 param_17 = p_local_1;
|
||||
float2 param_18 = ab;
|
||||
float _616 = sdEllipse(param_17, param_18);
|
||||
d = _616;
|
||||
if ((flags & 1u) != 0u)
|
||||
{
|
||||
float param_15 = d;
|
||||
float param_16 = stroke_px_2;
|
||||
d = sdf_stroke(param_15, param_16);
|
||||
float param_19 = d;
|
||||
float param_20 = stroke_px_2;
|
||||
d = sdf_stroke(param_19, param_20);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -220,10 +240,10 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
float2 b_1 = in.f_params.zw;
|
||||
float width = in.f_params2.x;
|
||||
soft = fast::max(in.f_params2.y, 1.0);
|
||||
float2 param_17 = in.f_local_or_uv;
|
||||
float2 param_18 = a;
|
||||
float2 param_19 = b_1;
|
||||
d = sdSegment(param_17, param_18, param_19) - (width * 0.5);
|
||||
float2 param_21 = in.f_local_or_uv;
|
||||
float2 param_22 = a;
|
||||
float2 param_23 = b_1;
|
||||
d = sdSegment(param_21, param_22, param_23) - (width * 0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -243,16 +263,16 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
}
|
||||
float ang_start = mod(start_rad, 6.283185482025146484375);
|
||||
float ang_end = mod(end_rad, 6.283185482025146484375);
|
||||
float _654;
|
||||
float _710;
|
||||
if (ang_end > ang_start)
|
||||
{
|
||||
_654 = float((angle >= ang_start) && (angle <= ang_end));
|
||||
_710 = float((angle >= ang_start) && (angle <= ang_end));
|
||||
}
|
||||
else
|
||||
{
|
||||
_654 = float((angle >= ang_start) || (angle <= ang_end));
|
||||
_710 = float((angle >= ang_start) || (angle <= ang_end));
|
||||
}
|
||||
float in_arc = _654;
|
||||
float in_arc = _710;
|
||||
if (abs(ang_end - ang_start) >= 6.282185077667236328125)
|
||||
{
|
||||
in_arc = 1.0;
|
||||
@@ -277,9 +297,9 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
d = (length(p) * cos(bn)) - radius_1;
|
||||
if ((flags & 1u) != 0u)
|
||||
{
|
||||
float param_20 = d;
|
||||
float param_21 = stroke_px_3;
|
||||
d = sdf_stroke(param_20, param_21);
|
||||
float param_24 = d;
|
||||
float param_25 = stroke_px_3;
|
||||
d = sdf_stroke(param_24, param_25);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,10 +307,9 @@ fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[textur
|
||||
}
|
||||
}
|
||||
}
|
||||
float param_22 = d;
|
||||
float param_23 = soft;
|
||||
float alpha = sdf_alpha(param_22, param_23);
|
||||
out.out_color = float4(in.f_color.xyz, in.f_color.w * alpha);
|
||||
float param_26 = d;
|
||||
float param_27 = soft;
|
||||
float alpha_1 = sdf_alpha(param_26, param_27);
|
||||
out.out_color = float4(in.f_color.xyz, in.f_color.w * alpha_1);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -19,6 +19,7 @@ struct Primitive
|
||||
float _pad;
|
||||
float4 params;
|
||||
float4 params2;
|
||||
float4 uv_rect;
|
||||
};
|
||||
|
||||
struct Primitive_1
|
||||
@@ -30,6 +31,7 @@ struct Primitive_1
|
||||
float _pad;
|
||||
float4 params;
|
||||
float4 params2;
|
||||
float4 uv_rect;
|
||||
};
|
||||
|
||||
struct Primitives
|
||||
@@ -45,6 +47,7 @@ struct main0_out
|
||||
float4 f_params2 [[user(locn3)]];
|
||||
uint f_kind_flags [[user(locn4)]];
|
||||
float f_rotation [[user(locn5)]];
|
||||
float4 f_uv_rect [[user(locn6)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
@@ -55,7 +58,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& _72 [[buffer(1)]], uint gl_InstanceIndex [[instance_id]])
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant Uniforms& _12 [[buffer(0)]], const device Primitives& _74 [[buffer(1)]], uint gl_InstanceIndex [[instance_id]])
|
||||
{
|
||||
main0_out out = {};
|
||||
if (_12.mode == 0u)
|
||||
@@ -66,18 +69,20 @@ vertex main0_out main0(main0_in in [[stage_in]], constant Uniforms& _12 [[buffer
|
||||
out.f_params2 = float4(0.0);
|
||||
out.f_kind_flags = 0u;
|
||||
out.f_rotation = 0.0;
|
||||
out.f_uv_rect = float4(0.0, 0.0, 1.0, 1.0);
|
||||
out.gl_Position = _12.projection * float4(in.v_position * _12.dpi_scale, 0.0, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Primitive p;
|
||||
p.bounds = _72.primitives[int(gl_InstanceIndex)].bounds;
|
||||
p.color = _72.primitives[int(gl_InstanceIndex)].color;
|
||||
p.kind_flags = _72.primitives[int(gl_InstanceIndex)].kind_flags;
|
||||
p.rotation = _72.primitives[int(gl_InstanceIndex)].rotation;
|
||||
p._pad = _72.primitives[int(gl_InstanceIndex)]._pad;
|
||||
p.params = _72.primitives[int(gl_InstanceIndex)].params;
|
||||
p.params2 = _72.primitives[int(gl_InstanceIndex)].params2;
|
||||
p.bounds = _74.primitives[int(gl_InstanceIndex)].bounds;
|
||||
p.color = _74.primitives[int(gl_InstanceIndex)].color;
|
||||
p.kind_flags = _74.primitives[int(gl_InstanceIndex)].kind_flags;
|
||||
p.rotation = _74.primitives[int(gl_InstanceIndex)].rotation;
|
||||
p._pad = _74.primitives[int(gl_InstanceIndex)]._pad;
|
||||
p.params = _74.primitives[int(gl_InstanceIndex)].params;
|
||||
p.params2 = _74.primitives[int(gl_InstanceIndex)].params2;
|
||||
p.uv_rect = _74.primitives[int(gl_InstanceIndex)].uv_rect;
|
||||
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;
|
||||
@@ -87,8 +92,8 @@ vertex main0_out main0(main0_in in [[stage_in]], constant Uniforms& _12 [[buffer
|
||||
out.f_params2 = p.params2;
|
||||
out.f_kind_flags = p.kind_flags;
|
||||
out.f_rotation = p.rotation;
|
||||
out.f_uv_rect = p.uv_rect;
|
||||
out.gl_Position = _12.projection * float4(world_pos * _12.dpi_scale, 0.0, 1.0);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -7,6 +7,7 @@ layout(location = 2) in vec4 f_params;
|
||||
layout(location = 3) in vec4 f_params2;
|
||||
layout(location = 4) flat in uint f_kind_flags;
|
||||
layout(location = 5) flat in float f_rotation;
|
||||
layout(location = 6) flat in vec4 f_uv_rect;
|
||||
|
||||
// --- Output ---
|
||||
layout(location = 0) out vec4 out_color;
|
||||
@@ -130,6 +131,23 @@ void main() {
|
||||
|
||||
d = sdRoundedBox(p_local, b, r);
|
||||
if ((flags & 1u) != 0u) d = sdf_stroke(d, stroke_px);
|
||||
|
||||
// Texture sampling for textured SDF primitives
|
||||
vec4 shape_color = f_color;
|
||||
if ((flags & 2u) != 0u) {
|
||||
// Compute UV from local position and half_size
|
||||
vec2 p_for_uv = f_local_or_uv;
|
||||
if (f_rotation != 0.0) {
|
||||
p_for_uv = apply_rotation(p_for_uv, f_rotation);
|
||||
}
|
||||
vec2 local_uv = p_for_uv / b * 0.5 + 0.5;
|
||||
vec2 uv = mix(f_uv_rect.xy, f_uv_rect.zw, local_uv);
|
||||
shape_color *= texture(tex, uv);
|
||||
}
|
||||
|
||||
float alpha = sdf_alpha(d, soft);
|
||||
out_color = vec4(shape_color.rgb, shape_color.a * alpha);
|
||||
return;
|
||||
}
|
||||
else if (kind == 2u) {
|
||||
// Circle — rotationally symmetric, no rotation needed
|
||||
|
||||
@@ -12,6 +12,7 @@ layout(location = 2) out vec4 f_params;
|
||||
layout(location = 3) out vec4 f_params2;
|
||||
layout(location = 4) flat out uint f_kind_flags;
|
||||
layout(location = 5) flat out float f_rotation;
|
||||
layout(location = 6) flat out vec4 f_uv_rect;
|
||||
|
||||
// ---------- Uniforms (single block — avoids spirv-cross reordering on Metal) ----------
|
||||
layout(set = 1, binding = 0) uniform Uniforms {
|
||||
@@ -29,6 +30,7 @@ struct Primitive {
|
||||
float _pad; // 28-31: alignment padding
|
||||
vec4 params; // 32-47: shape params part 1
|
||||
vec4 params2; // 48-63: shape params part 2
|
||||
vec4 uv_rect; // 64-79: u_min, v_min, u_max, v_max
|
||||
};
|
||||
|
||||
layout(std430, set = 0, binding = 0) readonly buffer Primitives {
|
||||
@@ -45,6 +47,7 @@ void main() {
|
||||
f_params2 = vec4(0.0);
|
||||
f_kind_flags = 0u;
|
||||
f_rotation = 0.0;
|
||||
f_uv_rect = vec4(0.0, 0.0, 1.0, 1.0);
|
||||
|
||||
gl_Position = projection * vec4(v_position * dpi_scale, 0.0, 1.0);
|
||||
} else {
|
||||
@@ -61,6 +64,7 @@ void main() {
|
||||
f_params2 = p.params2;
|
||||
f_kind_flags = p.kind_flags;
|
||||
f_rotation = p.rotation;
|
||||
f_uv_rect = p.uv_rect;
|
||||
|
||||
gl_Position = projection * vec4(world_pos * dpi_scale, 0.0, 1.0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user