Skip to content

Commit 7b8510a

Browse files
committed
Downsample shadow color texture
1 parent 7da35ee commit 7b8510a

1 file changed

Lines changed: 27 additions & 10 deletions

File tree

pathfinder/core/canvas.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
namespace Pathfinder {
1414

15+
constexpr float SHADOW_DOWNSAMPLING_SCALE = 0.5f;
16+
1517
struct ShadowBlurRenderTargetInfo {
1618
/// Render target ids.
1719
RenderTargetId id_x;
@@ -39,15 +41,18 @@ ShadowBlurRenderTargetInfo push_shadow_blur_render_targets(Scene &scene,
3941
return shadow_blur_info;
4042
}
4143

42-
auto sigma = current_state.shadow_blur * 0.5f;
44+
float sigma_original = current_state.shadow_blur * 0.5f;
45+
float sigma_scaled = sigma_original * SHADOW_DOWNSAMPLING_SCALE;
4346

4447
// Bounds expansion caused by blurring.
45-
auto bounds = outline_bounds.dilate(sigma * 3.f).round_out().to_i32();
48+
auto bounds = outline_bounds.dilate(sigma_original * 3.f).round_out().to_i32();
49+
50+
Vec2I scaled_size = (bounds.size().to_f32() * SHADOW_DOWNSAMPLING_SCALE).to_i32();
4651

47-
shadow_blur_info.id_y = scene.push_render_target(RenderTargetDesc{bounds.size(), "shadow blur x"});
48-
shadow_blur_info.id_x = scene.push_render_target(RenderTargetDesc{bounds.size(), "shadow blur y"});
52+
shadow_blur_info.id_y = scene.push_render_target(RenderTargetDesc{scaled_size, "shadow blur x"});
53+
shadow_blur_info.id_x = scene.push_render_target(RenderTargetDesc{scaled_size, "shadow blur y"});
4954

50-
shadow_blur_info.sigma = sigma;
55+
shadow_blur_info.sigma = sigma_scaled;
5156
shadow_blur_info.bounds = bounds;
5257

5358
shadow_blur_info.color = current_state.shadow_color;
@@ -65,9 +70,15 @@ void composite_shadow_blur_render_targets(Scene &scene, const ShadowBlurRenderTa
6570
return;
6671
}
6772

68-
auto pattern_x = Pattern::from_render_target(info.id_x, info.bounds.size());
69-
auto pattern_y = Pattern::from_render_target(info.id_y, info.bounds.size());
70-
pattern_y.apply_transform(Transform2::from_translation(info.bounds.origin().to_f32()));
73+
Vec2I scaled_size = (info.bounds.size().to_f32() * SHADOW_DOWNSAMPLING_SCALE).to_i32();
74+
75+
auto pattern_x = Pattern::from_render_target(info.id_x, scaled_size);
76+
auto pattern_y = Pattern::from_render_target(info.id_y, scaled_size);
77+
78+
Transform2 transform = Transform2::from_translation(info.bounds.origin().to_f32()) *
79+
Transform2::from_scale(Vec2F(1.0 / SHADOW_DOWNSAMPLING_SCALE));
80+
81+
pattern_y.apply_transform(transform);
7182

7283
auto filter = PatternFilter();
7384

@@ -93,7 +104,7 @@ void composite_shadow_blur_render_targets(Scene &scene, const ShadowBlurRenderTa
93104
DrawPath path_x;
94105
{
95106
Path2d path2d;
96-
path2d.add_rect({{0, 0}, info.bounds.size().to_f32()});
107+
path2d.add_rect({{0, 0}, scaled_size.to_f32()});
97108
path_x.outline = path2d.into_outline();
98109
}
99110
path_x.paint = paint_id_x;
@@ -170,7 +181,13 @@ void Canvas::push_path(Outline &outline, PathOp path_op, FillRule fill_rule) {
170181

171182
auto shadow_blur_info = push_shadow_blur_render_targets(*scene, current_state, shadow_outline.bounds);
172183

173-
shadow_outline.transform(Transform2::from_translation(-shadow_blur_info.bounds.origin().to_f32()));
184+
Vec2I scaled_size = (shadow_blur_info.bounds.size().to_f32() * SHADOW_DOWNSAMPLING_SCALE).to_i32();
185+
float inv_scale_x = (float)shadow_blur_info.bounds.width() / (float)scaled_size.x;
186+
float inv_scale_y = (float)shadow_blur_info.bounds.height() / (float)scaled_size.y;
187+
188+
// 输入端:先平移到局部原点,再缩小。对应顺序:Scale * Translate
189+
shadow_outline.transform(Transform2::from_scale(Vec2F(1.0f / inv_scale_x, 1.0f / inv_scale_y)) *
190+
Transform2::from_translation(-shadow_blur_info.bounds.origin().to_f32()));
174191

175192
// Per spec the shadow must respect the alpha of the shadowed path, but otherwise have
176193
// the color of the shadow paint.

0 commit comments

Comments
 (0)