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
This commit is contained in:
Sergii Liebodkin 2024-06-18 16:45:10 +03:00 committed by Hermet Park
parent 0d3d242f0c
commit 03c6f43441
3 changed files with 17 additions and 9 deletions

View file

@ -31,6 +31,10 @@
#define WG_VERTEX_BUFFER_MIN_SIZE 2048 #define WG_VERTEX_BUFFER_MIN_SIZE 2048
#define WG_INDEX_BUFFER_MIN_SIZE 2048 #define WG_INDEX_BUFFER_MIN_SIZE 2048
struct WgCompositor: public Compositor {
BlendMethod blendMethod;
};
enum class WgPipelineBlendType { enum class WgPipelineBlendType {
Src = 0, // S Src = 0, // S
Normal, // (Sa * S) + (255 - Sa) * D Normal, // (Sa * S) + (255 - Sa) * D

View file

@ -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) Compositor* WgRenderer::target(TVG_UNUSED const RenderRegion& region, TVG_UNUSED ColorSpace cs)
{ {
mCompositorStack.push(new Compositor); mCompositorStack.push(new WgCompositor);
return mCompositorStack.last(); 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) bool WgRenderer::beginComposite(TVG_UNUSED Compositor* cmp, TVG_UNUSED CompositeMethod method, TVG_UNUSED uint8_t opacity)
{ {
// save current composition settings // save current composition settings
cmp->method = method; WgCompositor *comp = (WgCompositor*)cmp;
cmp->opacity = opacity; comp->method = method;
comp->opacity = opacity;
comp->blendMethod = mBlendMethod;
// end current render pass // end current render pass
mRenderStorageStack.last()->endRenderPass(); mRenderStorageStack.last()->endRenderPass();
@ -355,7 +357,8 @@ bool WgRenderer::beginComposite(TVG_UNUSED Compositor* cmp, TVG_UNUSED Composite
bool WgRenderer::endComposite(TVG_UNUSED Compositor* cmp) 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 // end current render pass
mRenderStorageStack.last()->endRenderPass(); mRenderStorageStack.last()->endRenderPass();
// get two last render targets // get two last render targets
@ -363,7 +366,7 @@ bool WgRenderer::endComposite(TVG_UNUSED Compositor* cmp)
mRenderStorageStack.pop(); mRenderStorageStack.pop();
// blent scene to current render storage // 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); mRenderStorageStack.last()->blend(mCommandEncoder, renderStorageSrc, blendMethod);
// back render targets to the pool // back render targets to the pool
@ -382,9 +385,9 @@ bool WgRenderer::endComposite(TVG_UNUSED Compositor* cmp)
WgRenderStorage* renderStorageDst = mRenderStorageStack.last(); WgRenderStorage* renderStorageDst = mRenderStorageStack.last();
// get compose, blend and opacity settings // 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); WgBindGroupBlendMethod* blendMethod = mBlendMethodPool.allocate(mContext, mBlendMethod);
WgBindGroupOpacity* opacity = mOpacityPool.allocate(mContext, cmp->opacity); WgBindGroupOpacity* opacity = mOpacityPool.allocate(mContext, comp->opacity);
// compose and blend // compose and blend
// dest = blend(dest, compose(src, msk, composeMethod), blendMethod, opacity) // dest = blend(dest, compose(src, msk, composeMethod), blendMethod, opacity)

View file

@ -401,7 +401,7 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) {
/* Add */ case 1u: { color = (S + D); } /* Add */ case 1u: { color = (S + D); }
/* Screen */ case 2u: { color = (S + D) - (S * D); } /* Screen */ case 2u: { color = (S + D) - (S * D); }
/* Multiply */ case 3u: { color = (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); } /* Difference */ case 5u: { color = abs(S - D); }
/* Exclusion */ case 6u: { color = S + D - (2 * S * D); } /* Exclusion */ case 6u: { color = S + D - (2 * S * D); }
/* SrcOver */ case 7u: { color = S; } /* 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 colorSrc = textureLoad(imageSrc, id.xy);
let colorMsk = textureLoad(imageMsk, id.xy); let colorMsk = textureLoad(imageMsk, id.xy);
if ((length(colorSrc) == 0.0) || (length(colorMsk) == 0.0)) { return; };
let colorDst = textureLoad(imageDst, id.xy); let colorDst = textureLoad(imageDst, id.xy);
var color: vec3f = colorSrc.xyz; var color: vec3f = colorSrc.xyz;
@ -498,7 +499,7 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) {
/* Add */ case 1u: { color = (S + D); } /* Add */ case 1u: { color = (S + D); }
/* Screen */ case 2u: { color = (S + D) - (S * D); } /* Screen */ case 2u: { color = (S + D) - (S * D); }
/* Multiply */ case 3u: { color = (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); } /* Difference */ case 5u: { color = abs(S - D); }
/* Exclusion */ case 6u: { color = S + D - (2 * S * D); } /* Exclusion */ case 6u: { color = S + D - (2 * S * D); }
/* SrcOver */ case 7u: { color = S; } /* SrcOver */ case 7u: { color = S; }