diff --git a/src/renderer/wg_engine/tvgWgCompositor.cpp b/src/renderer/wg_engine/tvgWgCompositor.cpp index ba712645..435451be 100755 --- a/src/renderer/wg_engine/tvgWgCompositor.cpp +++ b/src/renderer/wg_engine/tvgWgCompositor.cpp @@ -908,5 +908,32 @@ bool WgCompositor::tintEffect(WgContext& context, WgRenderStorage* dst, const Re wgpuComputePassEncoderEnd(computePassEncoder); wgpuComputePassEncoderRelease(computePassEncoder); + return true; +} + +bool WgCompositor::tritoneEffect(WgContext& context, WgRenderStorage* dst, const RenderEffectFill* params, const WgCompose* compose) +{ + assert(dst); + assert(params); + assert(params->rd); + assert(compose->rdViewport); + assert(!renderPassEncoder); + + auto renderDataParams = (WgRenderDataEffectParams*)params->rd; + auto aabb = compose->aabb; + auto viewport = compose->rdViewport; + + copyTexture(&storageTemp0, dst, aabb); + WGPUComputePassDescriptor computePassDesc{ .label = "Compute pass tritone" }; + WGPUComputePassEncoder computePassEncoder = wgpuCommandEncoderBeginComputePass(commandEncoder, &computePassDesc); + wgpuComputePassEncoderSetBindGroup(computePassEncoder, 0, bindGroupStorageTemp, 0, nullptr); + wgpuComputePassEncoderSetBindGroup(computePassEncoder, 1, dst->bindGroupWrite, 0, nullptr); + wgpuComputePassEncoderSetBindGroup(computePassEncoder, 2, renderDataParams->bindGroupParams, 0, nullptr); + wgpuComputePassEncoderSetBindGroup(computePassEncoder, 3, viewport->bindGroupViewport, 0, nullptr); + wgpuComputePassEncoderSetPipeline(computePassEncoder, pipelines.tritone_effect); + wgpuComputePassEncoderDispatchWorkgroups(computePassEncoder, (aabb.w - 1) / 128 + 1, aabb.h, 1); + wgpuComputePassEncoderEnd(computePassEncoder); + wgpuComputePassEncoderRelease(computePassEncoder); + return true; } \ No newline at end of file diff --git a/src/renderer/wg_engine/tvgWgCompositor.h b/src/renderer/wg_engine/tvgWgCompositor.h index b2dcb776..3bc9a209 100755 --- a/src/renderer/wg_engine/tvgWgCompositor.h +++ b/src/renderer/wg_engine/tvgWgCompositor.h @@ -116,6 +116,7 @@ public: bool dropShadow(WgContext& context, WgRenderStorage* dst, const RenderEffectDropShadow* params, const WgCompose* compose); bool fillEffect(WgContext& context, WgRenderStorage* dst, const RenderEffectFill* params, const WgCompose* compose); bool tintEffect(WgContext& context, WgRenderStorage* dst, const RenderEffectFill* params, const WgCompose* compose); + bool tritoneEffect(WgContext& context, WgRenderStorage* dst, const RenderEffectFill* params, const WgCompose* compose); }; #endif // _TVG_WG_COMPOSITOR_H_ diff --git a/src/renderer/wg_engine/tvgWgPipelines.cpp b/src/renderer/wg_engine/tvgWgPipelines.cpp index ded394fc..765bbf68 100755 --- a/src/renderer/wg_engine/tvgWgPipelines.cpp +++ b/src/renderer/wg_engine/tvgWgPipelines.cpp @@ -455,6 +455,7 @@ void WgPipelines::initialize(WgContext& context) dropshadow = createComputePipeline(context.device, "The compute pipeline drop shadow blend", shader_effects, "cs_main_drop_shadow", layout_effects); fill_effect = createComputePipeline(context.device, "The compute pipeline fill effect", shader_effects, "cs_main_fill", layout_effects); tint_effect = createComputePipeline(context.device, "The compute pipeline tint effect", shader_effects, "cs_main_tint", layout_effects); + tritone_effect= createComputePipeline(context.device, "The compute pipeline tritone effect", shader_effects, "cs_main_tritone", layout_effects); } void WgPipelines::releaseGraphicHandles(WgContext& context) diff --git a/src/renderer/wg_engine/tvgWgPipelines.h b/src/renderer/wg_engine/tvgWgPipelines.h index a5f13d1c..ad3d2252 100755 --- a/src/renderer/wg_engine/tvgWgPipelines.h +++ b/src/renderer/wg_engine/tvgWgPipelines.h @@ -101,8 +101,9 @@ public: WGPUComputePipeline gaussian_horz{}; WGPUComputePipeline gaussian_vert{}; WGPUComputePipeline dropshadow{}; - WGPUComputePipeline fill_effect{}; - WGPUComputePipeline tint_effect{}; + WGPUComputePipeline fill_effect{}; + WGPUComputePipeline tint_effect{}; + WGPUComputePipeline tritone_effect{}; private: void releaseGraphicHandles(WgContext& context); WGPUShaderModule createShaderModule(WGPUDevice device, const char* label, const char* code); diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index d325c0e7..0f718c3d 100755 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -633,6 +633,15 @@ void WgRenderDataEffectParams::update(WgContext& context, const RenderEffectTint } +void WgRenderDataEffectParams::update(WgContext& context, const RenderEffectTritone* tritone) +{ + assert(tritone); + WgShaderTypeEffectParams effectParams; + effectParams.update(tritone); + update(context, effectParams); +} + + void WgRenderDataEffectParams::release(WgContext& context) { context.releaseBuffer(bufferParams); diff --git a/src/renderer/wg_engine/tvgWgRenderData.h b/src/renderer/wg_engine/tvgWgRenderData.h index 23fa0802..57f1d6c4 100755 --- a/src/renderer/wg_engine/tvgWgRenderData.h +++ b/src/renderer/wg_engine/tvgWgRenderData.h @@ -206,6 +206,7 @@ struct WgRenderDataEffectParams void update(WgContext& context, const RenderEffectDropShadow* dropShadow, const Matrix& transform); void update(WgContext& context, const RenderEffectFill* fill); void update(WgContext& context, const RenderEffectTint* tint); + void update(WgContext& context, const RenderEffectTritone* tritone); void release(WgContext& context); }; diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index 49b337c4..cc9076d1 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -564,6 +564,17 @@ void WgRenderer::prepare(RenderEffect* effect, const Matrix& transform) } renderData->update(mContext, renderEffect); effect->valid = true; + } else + // prepare tritone + if (effect->type == SceneEffect::Tritone) { + auto renderEffect = (RenderEffectTritone*)effect; + auto renderData = (WgRenderDataEffectParams*)renderEffect->rd; + if (!renderData) { + renderData = mRenderDataEffectParamsPool.allocate(mContext); + renderEffect->rd = renderData; + } + renderData->update(mContext, renderEffect); + effect->valid = true; } } @@ -610,6 +621,7 @@ bool WgRenderer::render(RenderCompositor* cmp, const RenderEffect* effect, TVG_U case SceneEffect::DropShadow: return mCompositor.dropShadow(mContext, dst, (RenderEffectDropShadow*)effect, comp); case SceneEffect::Fill: return mCompositor.fillEffect(mContext, dst, (RenderEffectFill*)effect, comp); case SceneEffect::Tint: return mCompositor.tintEffect(mContext, dst, (RenderEffectFill*)effect, comp); + case SceneEffect::Tritone : return mCompositor.tritoneEffect(mContext, dst, (RenderEffectFill*)effect, comp); default: return false; } return false; diff --git a/src/renderer/wg_engine/tvgWgShaderSrc.cpp b/src/renderer/wg_engine/tvgWgShaderSrc.cpp index 077bb2be..1e53d961 100755 --- a/src/renderer/wg_engine/tvgWgShaderSrc.cpp +++ b/src/renderer/wg_engine/tvgWgShaderSrc.cpp @@ -868,4 +868,26 @@ fn cs_main_tint(@builtin(global_invocation_id) gid: vec3u) { let color = mix(orig, mix(white, black, luma), intens) * orig.a; textureStore(imageTrg, uid.xy, color); } + +@compute @workgroup_size(128, 1) +fn cs_main_tritone(@builtin(global_invocation_id) gid: vec3u) { + // decode viewport and settings + let vmin = vec2u(viewport.xy); + let vmax = vec2u(viewport.zw); + + // tex coord + let uid = min(gid.xy + vmin, vmax); + + let orig = textureLoad(imageSrc, uid); + let luma: f32 = dot(orig.rgb, vec3f(0.2125, 0.7154, 0.0721)); + let shadow = settings[0]; + let midtone = settings[1]; + let highlight = settings[2]; + let color = select( + mix(shadow, midtone, luma * 2.0f), + mix(midtone, highlight, (luma - 0.5f)*2.0f), + luma >= 0.5f + ) * orig.a; + textureStore(imageTrg, uid.xy, color); +} )"; \ No newline at end of file diff --git a/src/renderer/wg_engine/tvgWgShaderTypes.cpp b/src/renderer/wg_engine/tvgWgShaderTypes.cpp index bfe00408..3d462bca 100755 --- a/src/renderer/wg_engine/tvgWgShaderTypes.cpp +++ b/src/renderer/wg_engine/tvgWgShaderTypes.cpp @@ -248,6 +248,7 @@ void WgShaderTypeEffectParams::update(const RenderEffectFill* fill) params[3] = fill->color[3] / 255.0f; } + void WgShaderTypeEffectParams::update(const RenderEffectTint* tint) { params[0] = tint->black[0] / 255.0f; @@ -259,4 +260,21 @@ void WgShaderTypeEffectParams::update(const RenderEffectTint* tint) params[6] = tint->white[2] / 255.0f; params[7] = 0.0f; params[8] = tint->intensity / 255.0f; -} \ No newline at end of file +} + + +void WgShaderTypeEffectParams::update(const RenderEffectTritone* tritone) +{ + params[0] = tritone->shadow[0] / 255.0f; + params[1] = tritone->shadow[1] / 255.0f; + params[2] = tritone->shadow[2] / 255.0f; + params[3] = 0.0f; + params[4] = tritone->midtone[0] / 255.0f; + params[5] = tritone->midtone[1] / 255.0f; + params[6] = tritone->midtone[2] / 255.0f; + params[7] = 0.0f; + params[8] = tritone->highlight[0] / 255.0f; + params[9] = tritone->highlight[1] / 255.0f; + params[10] = tritone->highlight[2] / 255.0f; + params[11] = 0.0f; +} diff --git a/src/renderer/wg_engine/tvgWgShaderTypes.h b/src/renderer/wg_engine/tvgWgShaderTypes.h index ddfed6b6..66853217 100755 --- a/src/renderer/wg_engine/tvgWgShaderTypes.h +++ b/src/renderer/wg_engine/tvgWgShaderTypes.h @@ -75,7 +75,8 @@ struct WgShaderTypeEffectParams // gaussian blur: [0]: sigma, [1]: scale, [2]: kernel size // drop shadow: [0]: sigma, [1]: scale, [2]: kernel size, [4..7]: color, [8, 9]: offset // fill: [0..3]: color - // tint: [0..2]: black, [4..6]: white, [8]: intensity + // tint: [0..2]: black, [4..6]: white, [8]: intensity + // tritone: [0..2]: shadow, [4..6]: midtone, [8..10]: highlight float params[4+4+4]{}; // settings: array; uint32_t extend{}; // gaussian blur extend Point offset{}; // drop shadow offset @@ -84,6 +85,7 @@ struct WgShaderTypeEffectParams void update(const RenderEffectDropShadow* dropShadow, const Matrix& transform); void update(const RenderEffectFill* fill); void update(const RenderEffectTint* tint); + void update(const RenderEffectTritone* tritone); }; #endif // _TVG_WG_SHADER_TYPES_H_