Allow passing a corner radius and borders to rendered images
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
co-authored by
Nathan Sobo
parent
96ade8668f
commit
95da665095
@@ -657,6 +657,8 @@ impl Renderer {
|
||||
for image in images {
|
||||
let origin = image.bounds.origin() * scale_factor;
|
||||
let target_size = image.bounds.size() * scale_factor;
|
||||
let corner_radius = image.corner_radius * scale_factor;
|
||||
let border_width = image.border.width * scale_factor;
|
||||
let (alloc_id, atlas_bounds) = self
|
||||
.prev_rendered_images
|
||||
.remove(&image.data.id)
|
||||
@@ -675,6 +677,12 @@ impl Renderer {
|
||||
target_size: target_size.to_float2(),
|
||||
source_size: atlas_bounds.size().to_float2(),
|
||||
atlas_origin: atlas_bounds.origin().to_float2(),
|
||||
border_top: border_width * (image.border.top as usize as f32),
|
||||
border_right: border_width * (image.border.right as usize as f32),
|
||||
border_bottom: border_width * (image.border.bottom as usize as f32),
|
||||
border_left: border_width * (image.border.left as usize as f32),
|
||||
border_color: image.border.color.to_uchar4(),
|
||||
corner_radius,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -97,4 +97,10 @@ typedef struct
|
||||
vector_float2 target_size;
|
||||
vector_float2 source_size;
|
||||
vector_float2 atlas_origin;
|
||||
float border_top;
|
||||
float border_right;
|
||||
float border_bottom;
|
||||
float border_left;
|
||||
vector_uchar4 border_color;
|
||||
float corner_radius;
|
||||
} GPUIImage;
|
||||
|
||||
@@ -34,46 +34,19 @@ float blur_along_x(float x, float y, float sigma, float corner, float2 halfSize)
|
||||
|
||||
struct QuadFragmentInput {
|
||||
float4 position [[position]];
|
||||
vector_float2 origin;
|
||||
vector_float2 size;
|
||||
vector_uchar4 background_color;
|
||||
float2 atlas_position; // only used in the image shader
|
||||
float2 origin;
|
||||
float2 size;
|
||||
float4 background_color;
|
||||
float border_top;
|
||||
float border_right;
|
||||
float border_bottom;
|
||||
float border_left;
|
||||
vector_uchar4 border_color;
|
||||
float4 border_color;
|
||||
float corner_radius;
|
||||
};
|
||||
|
||||
vertex QuadFragmentInput quad_vertex(
|
||||
uint unit_vertex_id [[vertex_id]],
|
||||
uint quad_id [[instance_id]],
|
||||
constant float2 *unit_vertices [[buffer(GPUIQuadInputIndexVertices)]],
|
||||
constant GPUIQuad *quads [[buffer(GPUIQuadInputIndexQuads)]],
|
||||
constant GPUIUniforms *uniforms [[buffer(GPUIQuadInputIndexUniforms)]]
|
||||
) {
|
||||
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
||||
GPUIQuad quad = quads[quad_id];
|
||||
float2 position = unit_vertex * quad.size + quad.origin;
|
||||
float4 device_position = to_device_position(position, uniforms->viewport_size);
|
||||
|
||||
return QuadFragmentInput {
|
||||
device_position,
|
||||
quad.origin,
|
||||
quad.size,
|
||||
quad.background_color,
|
||||
quad.border_top,
|
||||
quad.border_right,
|
||||
quad.border_bottom,
|
||||
quad.border_left,
|
||||
quad.border_color,
|
||||
quad.corner_radius,
|
||||
};
|
||||
}
|
||||
|
||||
fragment float4 quad_fragment(
|
||||
QuadFragmentInput input [[stage_in]]
|
||||
) {
|
||||
float4 quad_sdf(QuadFragmentInput input) {
|
||||
float2 half_size = input.size / 2.;
|
||||
float2 center = input.origin + half_size;
|
||||
float2 center_to_point = input.position.xy - center;
|
||||
@@ -95,12 +68,12 @@ fragment float4 quad_fragment(
|
||||
|
||||
float4 color;
|
||||
if (border_width == 0.) {
|
||||
color = coloru_to_colorf(input.background_color);
|
||||
color = input.background_color;
|
||||
} else {
|
||||
float inset_distance = distance + border_width;
|
||||
color = mix(
|
||||
coloru_to_colorf(input.border_color),
|
||||
coloru_to_colorf(input.background_color),
|
||||
input.border_color,
|
||||
input.background_color,
|
||||
saturate(0.5 - inset_distance)
|
||||
);
|
||||
}
|
||||
@@ -109,6 +82,39 @@ fragment float4 quad_fragment(
|
||||
return coverage * color;
|
||||
}
|
||||
|
||||
vertex QuadFragmentInput quad_vertex(
|
||||
uint unit_vertex_id [[vertex_id]],
|
||||
uint quad_id [[instance_id]],
|
||||
constant float2 *unit_vertices [[buffer(GPUIQuadInputIndexVertices)]],
|
||||
constant GPUIQuad *quads [[buffer(GPUIQuadInputIndexQuads)]],
|
||||
constant GPUIUniforms *uniforms [[buffer(GPUIQuadInputIndexUniforms)]]
|
||||
) {
|
||||
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
||||
GPUIQuad quad = quads[quad_id];
|
||||
float2 position = unit_vertex * quad.size + quad.origin;
|
||||
float4 device_position = to_device_position(position, uniforms->viewport_size);
|
||||
|
||||
return QuadFragmentInput {
|
||||
device_position,
|
||||
float2(0., 0.),
|
||||
quad.origin,
|
||||
quad.size,
|
||||
coloru_to_colorf(quad.background_color),
|
||||
quad.border_top,
|
||||
quad.border_right,
|
||||
quad.border_bottom,
|
||||
quad.border_left,
|
||||
coloru_to_colorf(quad.border_color),
|
||||
quad.corner_radius,
|
||||
};
|
||||
}
|
||||
|
||||
fragment float4 quad_fragment(
|
||||
QuadFragmentInput input [[stage_in]]
|
||||
) {
|
||||
return quad_sdf(input);
|
||||
}
|
||||
|
||||
struct ShadowFragmentInput {
|
||||
float4 position [[position]];
|
||||
vector_float2 origin;
|
||||
@@ -217,12 +223,7 @@ fragment float4 sprite_fragment(
|
||||
return color;
|
||||
}
|
||||
|
||||
struct ImageFragmentInput {
|
||||
float4 position [[position]];
|
||||
float2 atlas_position;
|
||||
};
|
||||
|
||||
vertex ImageFragmentInput image_vertex(
|
||||
vertex QuadFragmentInput image_vertex(
|
||||
uint unit_vertex_id [[vertex_id]],
|
||||
uint image_id [[instance_id]],
|
||||
constant float2 *unit_vertices [[buffer(GPUIImageVertexInputIndexVertices)]],
|
||||
@@ -236,18 +237,28 @@ vertex ImageFragmentInput image_vertex(
|
||||
float4 device_position = to_device_position(position, *viewport_size);
|
||||
float2 atlas_position = (unit_vertex * image.source_size + image.atlas_origin) / *atlas_size;
|
||||
|
||||
return ImageFragmentInput {
|
||||
return QuadFragmentInput {
|
||||
device_position,
|
||||
atlas_position,
|
||||
image.origin,
|
||||
image.target_size,
|
||||
float4(0.),
|
||||
image.border_top,
|
||||
image.border_right,
|
||||
image.border_bottom,
|
||||
image.border_left,
|
||||
coloru_to_colorf(image.border_color),
|
||||
image.corner_radius,
|
||||
};
|
||||
}
|
||||
|
||||
fragment float4 image_fragment(
|
||||
ImageFragmentInput input [[stage_in]],
|
||||
QuadFragmentInput input [[stage_in]],
|
||||
texture2d<float> atlas [[ texture(GPUIImageFragmentInputIndexAtlas) ]]
|
||||
) {
|
||||
constexpr sampler atlas_sampler(mag_filter::linear, min_filter::linear);
|
||||
return atlas.sample(atlas_sampler, input.atlas_position);
|
||||
input.background_color = atlas.sample(atlas_sampler, input.atlas_position);
|
||||
return quad_sdf(input);
|
||||
}
|
||||
|
||||
struct PathAtlasVertexOutput {
|
||||
|
||||
Reference in New Issue
Block a user