mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-17 13:34:57 +00:00
wg_engine: fix masking methods support
See Masking, InvMasking, LumaMasking, InvLumaMasking, MaskingMethods examples sw/webgpu
This commit is contained in:
parent
662dac075c
commit
8c4102362f
6 changed files with 36 additions and 130 deletions
|
@ -306,28 +306,6 @@ void WgPipelineBlend::initialize(WGPUDevice device, const char *shaderSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgPipelineCompose::initialize(WGPUDevice device)
|
|
||||||
{
|
|
||||||
// bind groups and layouts
|
|
||||||
WGPUBindGroupLayout bindGroupLayouts[] = {
|
|
||||||
WgBindGroupTextureStorageRgba::getLayout(device),
|
|
||||||
WgBindGroupTextureStorageRgba::getLayout(device),
|
|
||||||
WgBindGroupCompositeMethod::getLayout(device),
|
|
||||||
WgBindGroupOpacity::getLayout(device)
|
|
||||||
};
|
|
||||||
|
|
||||||
// sheder source and labels
|
|
||||||
auto shaderSource = cShaderSource_PipelineComputeCompose;
|
|
||||||
auto shaderLabel = "The compute shader compose";
|
|
||||||
auto pipelineLabel = "The compute pipeline compose";
|
|
||||||
|
|
||||||
// allocate all pipeline handles
|
|
||||||
allocate(device,
|
|
||||||
bindGroupLayouts, ARRAY_ELEMENTS_COUNT(bindGroupLayouts),
|
|
||||||
shaderSource, shaderLabel, pipelineLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WgPipelineComposeBlend::initialize(WGPUDevice device)
|
void WgPipelineComposeBlend::initialize(WGPUDevice device)
|
||||||
{
|
{
|
||||||
// bind groups and layouts
|
// bind groups and layouts
|
||||||
|
@ -390,7 +368,6 @@ void WgPipelines::initialize(WgContext& context)
|
||||||
computeBlendSolid.initialize(context.device, cShaderSource_PipelineComputeBlendSolid);
|
computeBlendSolid.initialize(context.device, cShaderSource_PipelineComputeBlendSolid);
|
||||||
computeBlendGradient.initialize(context.device, cShaderSource_PipelineComputeBlendGradient);
|
computeBlendGradient.initialize(context.device, cShaderSource_PipelineComputeBlendGradient);
|
||||||
computeBlendImage.initialize(context.device, cShaderSource_PipelineComputeBlendImage);
|
computeBlendImage.initialize(context.device, cShaderSource_PipelineComputeBlendImage);
|
||||||
computeCompose.initialize(context.device);
|
|
||||||
computeComposeBlend.initialize(context.device);
|
computeComposeBlend.initialize(context.device);
|
||||||
computeAntiAliasing.initialize(context.device);
|
computeAntiAliasing.initialize(context.device);
|
||||||
// store pipelines to context
|
// store pipelines to context
|
||||||
|
@ -415,7 +392,6 @@ void WgPipelines::release()
|
||||||
// compute pipelines
|
// compute pipelines
|
||||||
computeAntiAliasing.release();
|
computeAntiAliasing.release();
|
||||||
computeComposeBlend.release();
|
computeComposeBlend.release();
|
||||||
computeCompose.release();
|
|
||||||
computeBlendImage.release();
|
computeBlendImage.release();
|
||||||
computeBlendGradient.release();
|
computeBlendGradient.release();
|
||||||
computeBlendSolid.release();
|
computeBlendSolid.release();
|
||||||
|
|
|
@ -144,20 +144,6 @@ struct WgPipelineBlend: public WgComputePipeline
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct WgPipelineCompose: public WgComputePipeline
|
|
||||||
{
|
|
||||||
void initialize(WGPUDevice device) override;
|
|
||||||
void use(WGPUComputePassEncoder encoder, WgBindGroupTextureStorageRgba& groupTexSrc, WgBindGroupTextureStorageRgba& groupTexMsk, WgBindGroupCompositeMethod& groupComposeMethod, WgBindGroupOpacity& groupOpacity)
|
|
||||||
{
|
|
||||||
set(encoder);
|
|
||||||
groupTexSrc.set(encoder, 0);
|
|
||||||
groupTexMsk.set(encoder, 1);
|
|
||||||
groupComposeMethod.set(encoder, 2);
|
|
||||||
groupOpacity.set(encoder, 3);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct WgPipelineComposeBlend: public WgComputePipeline
|
struct WgPipelineComposeBlend: public WgComputePipeline
|
||||||
{
|
{
|
||||||
void initialize(WGPUDevice device) override;
|
void initialize(WGPUDevice device) override;
|
||||||
|
@ -203,7 +189,6 @@ struct WgPipelines
|
||||||
WgPipelineBlend computeBlendSolid;
|
WgPipelineBlend computeBlendSolid;
|
||||||
WgPipelineBlend computeBlendGradient;
|
WgPipelineBlend computeBlendGradient;
|
||||||
WgPipelineBlend computeBlendImage;
|
WgPipelineBlend computeBlendImage;
|
||||||
WgPipelineCompose computeCompose;
|
|
||||||
WgPipelineComposeBlend computeComposeBlend;
|
WgPipelineComposeBlend computeComposeBlend;
|
||||||
WgPipelineAntiAliasing computeAntiAliasing;
|
WgPipelineAntiAliasing computeAntiAliasing;
|
||||||
|
|
||||||
|
|
|
@ -184,17 +184,6 @@ void WgRenderStorage::blend(WGPUCommandEncoder commandEncoder, WgRenderStorage*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgRenderStorage::compose(WGPUCommandEncoder commandEncoder, WgRenderStorage* targetMsk, WgBindGroupCompositeMethod* composeMethod, WgBindGroupOpacity* opacity)
|
|
||||||
{
|
|
||||||
assert(commandEncoder);
|
|
||||||
assert(targetMsk);
|
|
||||||
WGPUComputePassEncoder computePassEncoder = beginComputePass(commandEncoder);
|
|
||||||
mPipelines->computeCompose.use(computePassEncoder, bindGroupTexStorageRgba, targetMsk->bindGroupTexStorageRgba, *composeMethod, *opacity);
|
|
||||||
dispatchWorkgroups(computePassEncoder);
|
|
||||||
endComputePass(computePassEncoder);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void WgRenderStorage::composeBlend(
|
void WgRenderStorage::composeBlend(
|
||||||
WgContext& context,
|
WgContext& context,
|
||||||
WGPUCommandEncoder commandEncoder,
|
WGPUCommandEncoder commandEncoder,
|
||||||
|
|
|
@ -54,7 +54,6 @@ public:
|
||||||
|
|
||||||
void clear(WGPUCommandEncoder commandEncoder);
|
void clear(WGPUCommandEncoder commandEncoder);
|
||||||
void blend(WGPUCommandEncoder commandEncoder, WgRenderStorage* targetSrc, WgPipelineBlend* pipeline, WgBindGroupBlendMethod* blendMethod, WgBindGroupOpacity* opacity);
|
void blend(WGPUCommandEncoder commandEncoder, WgRenderStorage* targetSrc, WgPipelineBlend* pipeline, WgBindGroupBlendMethod* blendMethod, WgBindGroupOpacity* opacity);
|
||||||
void compose(WGPUCommandEncoder commandEncoder, WgRenderStorage* targetMsk, WgBindGroupCompositeMethod* composeMethod, WgBindGroupOpacity* opacity);
|
|
||||||
void composeBlend(
|
void composeBlend(
|
||||||
WgContext& context,
|
WgContext& context,
|
||||||
WGPUCommandEncoder commandEncoder,
|
WGPUCommandEncoder commandEncoder,
|
||||||
|
|
|
@ -494,41 +494,6 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// pipeline shader modules compose
|
|
||||||
const char* cShaderSource_PipelineComputeCompose = WG_SHADER_SOURCE(
|
|
||||||
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read_write>;
|
|
||||||
@group(1) @binding(0) var imageMsk : texture_storage_2d<rgba8unorm, read_write>;
|
|
||||||
@group(2) @binding(0) var<uniform> composeMethod : u32;
|
|
||||||
@group(3) @binding(0) var<uniform> opacity : f32;
|
|
||||||
|
|
||||||
@compute @workgroup_size(8, 8)
|
|
||||||
fn cs_main( @builtin(global_invocation_id) id: vec3u) {
|
|
||||||
let texSize = textureDimensions(imageSrc);
|
|
||||||
if ((id.x >= texSize.x) || (id.y >= texSize.y)) { return; };
|
|
||||||
|
|
||||||
let colorSrc = textureLoad(imageSrc, id.xy);
|
|
||||||
let colorMsk = textureLoad(imageMsk, id.xy);
|
|
||||||
|
|
||||||
var color: vec3f = colorSrc.xyz;
|
|
||||||
var alpha: f32 = colorMsk.a;
|
|
||||||
switch composeMethod {
|
|
||||||
/* None */ case 0u: { color = colorSrc.xyz; }
|
|
||||||
/* ClipPath */ case 1u: { if (colorMsk.a == 0) { alpha = 0.0; }; }
|
|
||||||
/* AlphaMask */ case 2u: { color = mix(colorMsk.xyz, colorSrc.xyz, colorSrc.a * colorMsk.b); }
|
|
||||||
/* InvAlphaMask */ case 3u: { color = mix(colorSrc.xyz, colorMsk.xyz, colorSrc.a * colorMsk.b); alpha = 1.0 - colorMsk.b; }
|
|
||||||
/* LumaMask */ case 4u: { color = colorSrc.xyz * (0.299 * colorMsk.r + 0.587 * colorMsk.g + 0.114 * colorMsk.b); }
|
|
||||||
/* InvLumaMask */ case 5u: { color = colorSrc.xyz * (1.0 - (0.299 * colorMsk.r + 0.587 * colorMsk.g + 0.114 * colorMsk.b)); alpha = 1.0 - colorMsk.b; }
|
|
||||||
/* AddMask */ case 6u: { color = colorSrc.xyz * colorSrc.a + colorMsk.xyz * (1.0 - colorSrc.a); }
|
|
||||||
/* SubtractMask */ case 7u: { color = colorSrc.xyz * colorSrc.a - colorMsk.xyz * (1.0 - colorSrc.a); }
|
|
||||||
/* IntersectMask */ case 8u: { color = colorSrc.xyz * min(colorSrc.a, colorMsk.a); }
|
|
||||||
/* DifferenceMask */ case 9u: { color = abs(colorSrc.xyz - colorMsk.xyz * (1.0 - colorMsk.a)); }
|
|
||||||
default: { color = colorSrc.xyz; }
|
|
||||||
}
|
|
||||||
|
|
||||||
textureStore(imageSrc, id.xy, vec4f(color, alpha * opacity));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// pipeline shader modules compose blend
|
// pipeline shader modules compose blend
|
||||||
const char* cShaderSource_PipelineComputeComposeBlend = WG_SHADER_SOURCE(
|
const char* cShaderSource_PipelineComputeComposeBlend = WG_SHADER_SOURCE(
|
||||||
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read>;
|
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read>;
|
||||||
|
@ -545,53 +510,46 @@ 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 result: vec3f = colorSrc.xyz;
|
var One: vec3f = vec3(1.0);
|
||||||
var alpha: f32 = colorMsk.a;
|
let luma: f32 = dot(colorMsk.xyz, vec3f(0.2125, 0.7154, 0.0721));
|
||||||
let luma: f32 = dot(colorMsk.xyz, vec3f(0.299, 0.587, 0.114));
|
var So : f32 = opacity;
|
||||||
|
var Mc : vec3f = colorMsk.rgb;
|
||||||
|
var Ma : f32 = colorMsk.a;
|
||||||
|
var MSc : vec3f = colorSrc.rgb;
|
||||||
|
var MSa : f32 = colorSrc.a;
|
||||||
|
var Sc : vec3f = colorSrc.rgb;
|
||||||
|
var Sa : f32 = colorSrc.a;
|
||||||
|
var Dc : vec3f = colorDst.rgb;
|
||||||
|
var Da : f32 = colorDst.a;
|
||||||
|
var Rc : vec3f = colorDst.rgb;
|
||||||
|
var Ra : f32 = 1.0;
|
||||||
|
|
||||||
|
if (composeMethod <= /* InvLumaMask */5u) {
|
||||||
switch composeMethod {
|
switch composeMethod {
|
||||||
/* None */ case 0u: { result = colorSrc.xyz; }
|
/* AlphaMask */ case 2u: { Sc = MSc * Ma; Sa = MSa * Ma; }
|
||||||
/* ClipPath */ case 1u: { if (colorMsk.a == 0) { alpha = 0.0; }; }
|
/* InvAlphaMask */ case 3u: { Sc = MSc * (1.0 - Ma); Sa = MSa * (1.0 - Ma); }
|
||||||
/* AlphaMask */ case 2u: { result = colorSrc.xyz; alpha = colorSrc.a * colorMsk.a; }
|
/* LumaMask */ case 4u: { Sc = MSc * luma; Sa = MSa * luma; }
|
||||||
/* InvAlphaMask */ case 3u: { result = colorSrc.xyz; alpha = colorSrc.a * (1.0 - colorMsk.a); }
|
/* InvLumaMask */ case 5u: { Sc = MSc * (1.0-luma); Sa = MSa * (1.0-luma); }
|
||||||
/* LumaMask */ case 4u: { result = colorSrc.xyz; alpha = colorSrc.a * luma; }
|
default: { Sc = MSc; Sa = MSa; }
|
||||||
/* InvLumaMask */ case 5u: { result = colorSrc.xyz; alpha = colorSrc.a * (1.0 - luma); }
|
}
|
||||||
/* AddMask */ case 6u: { result = colorSrc.xyz * colorSrc.a + colorMsk.xyz * (1.0 - colorSrc.a); }
|
Rc = Sc + Dc * (1.0 - Sa);
|
||||||
/* SubtractMask */ case 7u: { result = colorSrc.xyz * colorSrc.a - colorMsk.xyz * (1.0 - colorSrc.a); }
|
Ra = Sa + Da * (1.0 - Sa);
|
||||||
/* IntersectMask */ case 8u: { result = colorSrc.xyz * min(colorSrc.a, colorMsk.a); }
|
} else {
|
||||||
/* DifferenceMask */ case 9u: { result = abs(colorMsk.xyz - colorSrc.xyz * (1.0 - colorMsk.a)); }
|
Sc = Dc;
|
||||||
default: { result = colorSrc.xyz; }
|
switch composeMethod {
|
||||||
|
/* AddMask */ case 6u: { Sa = MSa + Ma * (1.0 - MSa); }
|
||||||
|
/* SubtractMask */ case 7u: { Sa = MSa * (1.0 - Ma); }
|
||||||
|
/* IntersectMask */ case 8u: { Sa = MSa * Ma; }
|
||||||
|
/* DifferenceMask */ case 9u: { Sa = MSa * (1.0 - Ma) + Ma * (1.0 - MSa); }
|
||||||
|
default: { Rc = Sc; Ra = Sa; }
|
||||||
|
}
|
||||||
|
Rc = Sc;
|
||||||
|
Ra = Sa;
|
||||||
}
|
}
|
||||||
|
|
||||||
let So: f32 = opacity;
|
textureStore(imageDst, id.xy, vec4f(Rc, Ra));
|
||||||
let Sa: f32 = alpha;
|
|
||||||
let Da: f32 = colorDst.a;
|
|
||||||
let S: vec4f = vec4(result, alpha);
|
|
||||||
let D: vec4f = colorDst;
|
|
||||||
let One: vec4f = vec4(1.0);
|
|
||||||
|
|
||||||
var color: vec4f = vec4f(0.0, 0.0, 0.0, 0.0);
|
|
||||||
switch blendMethod {
|
|
||||||
/* Normal */ case 0u: { color = (S * So) + (1.0 - Sa * So) * D; }
|
|
||||||
/* Add */ case 1u: { color = (S + D); }
|
|
||||||
/* Screen */ case 2u: { color = (S + D) - (S * D); }
|
|
||||||
/* Multiply */ case 3u: { 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; }
|
|
||||||
/* Darken */ case 8u: { color = min(S, D); }
|
|
||||||
/* Lighten */ case 9u: { color = max(S, D); }
|
|
||||||
/* ColorDodge */ case 10u: { color = D / (One - S); }
|
|
||||||
/* ColorBurn */ case 11u: { color = One - (One - D) / S; }
|
|
||||||
/* HardLight */ case 12u: { color = (Sa * Da) - 2.0 * (Da - S) * (Sa - D); }
|
|
||||||
/* SoftLight */ case 13u: { color = (One - 2 * S) * (D * D) + (2 * S * D); }
|
|
||||||
default: { color = (S * So) + (1.0 - Sa * So) * D; }
|
|
||||||
}
|
|
||||||
|
|
||||||
textureStore(imageDst, id.xy, color);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ extern const char* cShaderSource_PipelineComputeClear;
|
||||||
extern const char* cShaderSource_PipelineComputeBlendSolid;
|
extern const char* cShaderSource_PipelineComputeBlendSolid;
|
||||||
extern const char* cShaderSource_PipelineComputeBlendGradient;
|
extern const char* cShaderSource_PipelineComputeBlendGradient;
|
||||||
extern const char* cShaderSource_PipelineComputeBlendImage;
|
extern const char* cShaderSource_PipelineComputeBlendImage;
|
||||||
extern const char* cShaderSource_PipelineComputeCompose;
|
|
||||||
extern const char* cShaderSource_PipelineComputeComposeBlend;
|
extern const char* cShaderSource_PipelineComputeComposeBlend;
|
||||||
extern const char* cShaderSource_PipelineComputeAntiAlias;
|
extern const char* cShaderSource_PipelineComputeAntiAlias;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue