From 03c6f43441196e481520c5305151341485ea8da4 Mon Sep 17 00:00:00 2001 From: Sergii Liebodkin Date: Tue, 18 Jun 2024 16:45:10 +0300 Subject: [PATCH] wg_engine: fix scene rendering with blend Fix allplience of the blend method, that setuped for scene, but not for a shape Overlay blend func changed to be close to spec --- src/renderer/wg_engine/tvgWgCommon.h | 4 ++++ src/renderer/wg_engine/tvgWgRenderer.cpp | 17 ++++++++++------- src/renderer/wg_engine/tvgWgShaderSrc.cpp | 5 +++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/renderer/wg_engine/tvgWgCommon.h b/src/renderer/wg_engine/tvgWgCommon.h index 65db5a50..9edac4fa 100644 --- a/src/renderer/wg_engine/tvgWgCommon.h +++ b/src/renderer/wg_engine/tvgWgCommon.h @@ -31,6 +31,10 @@ #define WG_VERTEX_BUFFER_MIN_SIZE 2048 #define WG_INDEX_BUFFER_MIN_SIZE 2048 +struct WgCompositor: public Compositor { + BlendMethod blendMethod; +}; + enum class WgPipelineBlendType { Src = 0, // S Normal, // (Sa * S) + (255 - Sa) * D diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index b59327e6..001faa8f 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -331,7 +331,7 @@ bool WgRenderer::target(WGPUInstance instance, WGPUSurface surface, uint32_t w, Compositor* WgRenderer::target(TVG_UNUSED const RenderRegion& region, TVG_UNUSED ColorSpace cs) { - mCompositorStack.push(new Compositor); + mCompositorStack.push(new WgCompositor); return mCompositorStack.last(); } @@ -339,8 +339,10 @@ Compositor* WgRenderer::target(TVG_UNUSED const RenderRegion& region, TVG_UNUSED bool WgRenderer::beginComposite(TVG_UNUSED Compositor* cmp, TVG_UNUSED CompositeMethod method, TVG_UNUSED uint8_t opacity) { // save current composition settings - cmp->method = method; - cmp->opacity = opacity; + WgCompositor *comp = (WgCompositor*)cmp; + comp->method = method; + comp->opacity = opacity; + comp->blendMethod = mBlendMethod; // end current render pass mRenderStorageStack.last()->endRenderPass(); @@ -355,7 +357,8 @@ bool WgRenderer::beginComposite(TVG_UNUSED Compositor* cmp, TVG_UNUSED Composite bool WgRenderer::endComposite(TVG_UNUSED Compositor* cmp) { - if (cmp->method == CompositeMethod::None) { + WgCompositor *comp = (WgCompositor*)cmp; + if (comp->method == CompositeMethod::None) { // end current render pass mRenderStorageStack.last()->endRenderPass(); // get two last render targets @@ -363,7 +366,7 @@ bool WgRenderer::endComposite(TVG_UNUSED Compositor* cmp) mRenderStorageStack.pop(); // blent scene to current render storage - WgBindGroupBlendMethod* blendMethod = mBlendMethodPool.allocate(mContext, mBlendMethod); + WgBindGroupBlendMethod* blendMethod = mBlendMethodPool.allocate(mContext, comp->blendMethod); mRenderStorageStack.last()->blend(mCommandEncoder, renderStorageSrc, blendMethod); // back render targets to the pool @@ -382,9 +385,9 @@ bool WgRenderer::endComposite(TVG_UNUSED Compositor* cmp) WgRenderStorage* renderStorageDst = mRenderStorageStack.last(); // get compose, blend and opacity settings - WgBindGroupCompositeMethod* composeMethod = mCompositeMethodPool.allocate(mContext, cmp->method); + WgBindGroupCompositeMethod* composeMethod = mCompositeMethodPool.allocate(mContext, comp->method); WgBindGroupBlendMethod* blendMethod = mBlendMethodPool.allocate(mContext, mBlendMethod); - WgBindGroupOpacity* opacity = mOpacityPool.allocate(mContext, cmp->opacity); + WgBindGroupOpacity* opacity = mOpacityPool.allocate(mContext, comp->opacity); // compose and blend // dest = blend(dest, compose(src, msk, composeMethod), blendMethod, opacity) diff --git a/src/renderer/wg_engine/tvgWgShaderSrc.cpp b/src/renderer/wg_engine/tvgWgShaderSrc.cpp index 781170d5..ce394208 100644 --- a/src/renderer/wg_engine/tvgWgShaderSrc.cpp +++ b/src/renderer/wg_engine/tvgWgShaderSrc.cpp @@ -401,7 +401,7 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) { /* Add */ case 1u: { color = (S + D); } /* Screen */ case 2u: { color = (S + D) - (S * D); } /* Multiply */ case 3u: { color = (S * D); } - /* Overlay */ case 4u: { color = S * D; } + /* Overlay */ case 4u: { color = (Sa * Da) - 2 * (Da - S) * (Sa - D); } /* Difference */ case 5u: { color = abs(S - D); } /* Exclusion */ case 6u: { color = S + D - (2 * S * D); } /* SrcOver */ case 7u: { color = S; } @@ -469,6 +469,7 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) { let colorSrc = textureLoad(imageSrc, id.xy); let colorMsk = textureLoad(imageMsk, id.xy); + if ((length(colorSrc) == 0.0) || (length(colorMsk) == 0.0)) { return; }; let colorDst = textureLoad(imageDst, id.xy); var color: vec3f = colorSrc.xyz; @@ -498,7 +499,7 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) { /* Add */ case 1u: { color = (S + D); } /* Screen */ case 2u: { color = (S + D) - (S * D); } /* Multiply */ case 3u: { color = (S * D); } - /* Overlay */ case 4u: { color = S * D; } + /* Overlay */ case 4u: { color = (Sa * Da) - 2 * (Da - S) * (Sa - D); } /* Difference */ case 5u: { color = abs(S - D); } /* Exclusion */ case 6u: { color = S + D - (2 * S * D); } /* SrcOver */ case 7u: { color = S; }