gl/wg engines: zero size blur dropshadow support
Some checks failed
Android / build_x86_64 (push) Has been cancelled
Android / build_aarch64 (push) Has been cancelled
iOS / build_x86_64 (push) Has been cancelled
iOS / build_arm64 (push) Has been cancelled
macOS / build (push) Has been cancelled
macOS / compact_test (push) Has been cancelled
macOS / unit_test (push) Has been cancelled
Ubuntu / build (push) Has been cancelled
Ubuntu / compact_test (push) Has been cancelled
Ubuntu / unit_test (push) Has been cancelled
Windows / build (push) Has been cancelled
Windows / compact_test (push) Has been cancelled
Windows / unit_test (push) Has been cancelled

- Implements support for zero size blur in drop shadow effects for both GL and WebGPU engines.
  When the blur sigma parameter is zero, the implementation now skips the blur processing entirely
  and uses the original image as the shadow source.  Improving performance and avoiding
  unnecessary computations

- EffectDropShadow example changed to reproduce zero sigma shadow

https://github.com/thorvg/thorvg/issues/3602
This commit is contained in:
Sergii Liebodkin 2025-07-23 19:37:12 +03:00 committed by Hermet Park
parent dfa3efdb4e
commit 86e4310a14
6 changed files with 27 additions and 23 deletions

View file

@ -103,7 +103,7 @@ struct UserExample : tvgexam::Example
scene2->push(tvg::SceneEffect::DropShadow, 65, 143, 222, (int)(255.0f * progress), 135.0, 10.0, 3.0, 100); scene2->push(tvg::SceneEffect::DropShadow, 65, 143, 222, (int)(255.0f * progress), 135.0, 10.0, 3.0, 100);
scene3->push(tvg::SceneEffect::ClearAll); scene3->push(tvg::SceneEffect::ClearAll);
scene3->push(tvg::SceneEffect::DropShadow, 0, 0, 0, 125, (double)(360.0f * progress), 20.0, 3.0, 100); scene3->push(tvg::SceneEffect::DropShadow, 0, 0, 0, 125, (double)(360.0f * progress), 20.0, 0.0, 100);
canvas->update(); canvas->update();

View file

@ -141,7 +141,7 @@ void GlEffect::update(RenderEffectDropShadow* effect, const Matrix& transform)
dropShadow->offset[1] = offset.y; dropShadow->offset[1] = offset.y;
dropShadow->extend = 2 * std::max(sigma * scale + std::abs(offset.x), sigma * scale + std::abs(offset.y)); dropShadow->extend = 2 * std::max(sigma * scale + std::abs(offset.x), sigma * scale + std::abs(offset.y));
effect->rd = dropShadow; effect->rd = dropShadow;
effect->valid = (dropShadow->extend > 0); effect->valid = (dropShadow->extend >= 0);
} }

View file

@ -544,6 +544,8 @@ void GlEffectDropShadowTask::run()
GL_CHECK(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST)); GL_CHECK(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST));
GL_CHECK(glDisable(GL_BLEND)); GL_CHECK(glDisable(GL_BLEND));
// when sigma is 0, no blur is applied, and the original image is used directly as the shadow.
if (!tvg::zero(effect->sigma)) {
// horizontal blur // horizontal blur
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mDstCopyFbo0->getResolveFboId())); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mDstCopyFbo0->getResolveFboId()));
horzTask->setViewport(vp); horzTask->setViewport(vp);
@ -558,6 +560,7 @@ void GlEffectDropShadowTask::run()
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, mDstFbo->getFboId())); GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, mDstFbo->getFboId()));
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDstCopyFbo0->getResolveFboId())); GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDstCopyFbo0->getResolveFboId()));
GL_CHECK(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST)); GL_CHECK(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST));
}
// run drop shadow effect // run drop shadow effect
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mDstFbo->getFboId())); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mDstFbo->getFboId()));
GlRenderTask::run(); GlRenderTask::run();

View file

@ -875,8 +875,9 @@ bool WgCompositor::dropShadow(WgContext& context, WgRenderTarget* dst, const Ren
auto aabb = compose->aabb; auto aabb = compose->aabb;
auto viewport = compose->rdViewport; auto viewport = compose->rdViewport;
{ // apply blur
copyTexture(&targetTemp1, dst, aabb); copyTexture(&targetTemp1, dst, aabb);
// when sigma is 0, no blur is applied, and the original image is used directly as the shadow.
if (!tvg::zero(params->sigma)) {
WgRenderTarget* sbuff = &targetTemp1; WgRenderTarget* sbuff = &targetTemp1;
WgRenderTarget* dbuff = &targetTemp0; WgRenderTarget* dbuff = &targetTemp0;
WGPUComputePassDescriptor computePassDesc{ .label = "Compute pass drop shadow blur" }; WGPUComputePassDescriptor computePassDesc{ .label = "Compute pass drop shadow blur" };

View file

@ -538,10 +538,10 @@ bool WgRenderer::region(RenderEffect* effect)
} else if (effect->type == SceneEffect::DropShadow) { } else if (effect->type == SceneEffect::DropShadow) {
auto dropShadow = (RenderEffectDropShadow*)effect; auto dropShadow = (RenderEffectDropShadow*)effect;
auto renderData = (WgRenderDataEffectParams*)dropShadow->rd; auto renderData = (WgRenderDataEffectParams*)dropShadow->rd;
dropShadow->extend.min.x = -(renderData->extend + std::abs(renderData->offset.x)); dropShadow->extend.min.x = -std::ceil(renderData->extend + std::abs(renderData->offset.x));
dropShadow->extend.max.x = +(renderData->extend + std::abs(renderData->offset.x)); dropShadow->extend.min.y = -std::ceil(renderData->extend + std::abs(renderData->offset.y));
dropShadow->extend.min.y = -(renderData->extend + std::abs(renderData->offset.y)); dropShadow->extend.max.x = +std::floor(renderData->extend + std::abs(renderData->offset.x));
dropShadow->extend.max.y = +(renderData->extend + std::abs(renderData->offset.y)); dropShadow->extend.max.y = +std::floor(renderData->extend + std::abs(renderData->offset.y));
return true; return true;
} }
return false; return false;

View file

@ -247,7 +247,7 @@ bool WgShaderTypeEffectParams::update(RenderEffectDropShadow* dropShadow, const
params[9] = offset.y; params[9] = offset.y;
extend = params[2] * 2; // kernel extend = params[2] * 2; // kernel
dropShadow->valid = (extend > 0); dropShadow->valid = (extend >= 0);
return dropShadow->valid; return dropShadow->valid;
} }