mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
gl_engine: Introduce tritone effect for opengl renderer
issue: https://github.com/thorvg/thorvg/issues/3054
This commit is contained in:
parent
95f1b84a56
commit
eb67549295
6 changed files with 63 additions and 10 deletions
|
@ -211,6 +211,7 @@ struct GlGaussianBlur {
|
|||
struct GlEffectParams {
|
||||
// fill: [0..3]: color
|
||||
// tint: [0..2]: black, [4..6]: white, [8]: intensity
|
||||
// tritone: [0..2]: shadow, [4..6]: midtone, [8..10]: highlight
|
||||
float params[4+4+4];
|
||||
};
|
||||
|
||||
|
|
|
@ -437,7 +437,6 @@ void GlGaussianBlurTask::run()
|
|||
|
||||
void GlEffectColorTransformTask::run()
|
||||
{
|
||||
// const auto vp = getViewport();
|
||||
const auto width = mDstFbo->getWidth();
|
||||
const auto height = mDstFbo->getHeight();
|
||||
// get targets handles and pass to shader
|
||||
|
@ -447,7 +446,7 @@ void GlEffectColorTransformTask::run()
|
|||
|
||||
GL_CHECK(glViewport(0, 0, width, height));
|
||||
GL_CHECK(glScissor(0, 0, width, height));
|
||||
// we need to make full copy of dst to intermidiate buffers to be shure, that they are not containe prev data
|
||||
// we need to make a full copy of dst to intermediate buffers to be sure that they don’t contain prev data.
|
||||
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, mDstFbo->getFboId()));
|
||||
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDstCopyFbo->getResolveFboId()));
|
||||
GL_CHECK(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
|
|
|
@ -146,6 +146,7 @@ void GlRenderer::initShaders()
|
|||
mPrograms.push(new GlProgram(EFFECT_VERTEX, GAUSSIAN_HORIZONTAL));
|
||||
mPrograms.push(new GlProgram(EFFECT_VERTEX, EFFECT_FILL));
|
||||
mPrograms.push(new GlProgram(EFFECT_VERTEX, EFFECT_TINT));
|
||||
mPrograms.push(new GlProgram(EFFECT_VERTEX, EFFECT_TRITONE));
|
||||
}
|
||||
|
||||
|
||||
|
@ -994,6 +995,27 @@ void GlRenderer::effectTintUpdate(RenderEffectTint* effect, const Matrix& transf
|
|||
}
|
||||
|
||||
|
||||
void GlRenderer::effectTritoneUpdate(RenderEffectTritone* effect, const Matrix& transform)
|
||||
{
|
||||
auto params = (GlEffectParams*)effect->rd;
|
||||
if (!params) params = tvg::malloc<GlEffectParams*>(sizeof(GlEffectParams));
|
||||
params->params[0] = effect->shadow[0] / 255.0f;
|
||||
params->params[1] = effect->shadow[1] / 255.0f;
|
||||
params->params[2] = effect->shadow[2] / 255.0f;
|
||||
params->params[3] = 0.0f;
|
||||
params->params[4] = effect->midtone[0] / 255.0f;
|
||||
params->params[5] = effect->midtone[1] / 255.0f;
|
||||
params->params[6] = effect->midtone[2] / 255.0f;
|
||||
params->params[7] = 0.0f;
|
||||
params->params[8] = effect->highlight[0] / 255.0f;
|
||||
params->params[9] = effect->highlight[1] / 255.0f;
|
||||
params->params[10] = effect->highlight[2] / 255.0f;
|
||||
params->params[11] = 0.0f;
|
||||
effect->rd = params;
|
||||
effect->valid = true;
|
||||
}
|
||||
|
||||
|
||||
bool GlRenderer::effectGaussianBlurRegion(RenderEffectGaussianBlur* effect)
|
||||
{
|
||||
auto gaussianBlur = (GlGaussianBlur*)effect->rd;
|
||||
|
@ -1019,6 +1041,7 @@ void GlRenderer::prepare(RenderEffect* effect, const Matrix& transform)
|
|||
case SceneEffect::GaussianBlur: effectGaussianBlurUpdate(static_cast<RenderEffectGaussianBlur*>(effect), transform); break;
|
||||
case SceneEffect::Fill: effectFillUpdate(static_cast<RenderEffectFill*>(effect), transform); break;
|
||||
case SceneEffect::Tint: effectTintUpdate(static_cast<RenderEffectTint*>(effect), transform); break;
|
||||
case SceneEffect::Tritone: effectTritoneUpdate(static_cast<RenderEffectTritone*>(effect), transform); break;
|
||||
default: break;
|
||||
}
|
||||
effect->valid = true;
|
||||
|
@ -1029,8 +1052,9 @@ bool GlRenderer::region(RenderEffect* effect)
|
|||
{
|
||||
switch (effect->type) {
|
||||
case SceneEffect::GaussianBlur: return effectGaussianBlurRegion(static_cast<RenderEffectGaussianBlur*>(effect));
|
||||
case SceneEffect::Fill: return true;
|
||||
case SceneEffect::Tint: return true;
|
||||
case SceneEffect::Fill:
|
||||
case SceneEffect::Tint:
|
||||
case SceneEffect::Tritone: return true;
|
||||
default: return false;
|
||||
}
|
||||
return false;
|
||||
|
@ -1079,17 +1103,19 @@ bool GlRenderer::render(TVG_UNUSED RenderCompositor* cmp, const RenderEffect* ef
|
|||
// add task to render pipeline
|
||||
pass->addRenderTask(gaussianTask);
|
||||
} // effect fill
|
||||
else if ((effect->type == SceneEffect::Fill) || (effect->type == SceneEffect::Tint)) {
|
||||
else if ((effect->type == SceneEffect::Fill) || (effect->type == SceneEffect::Tint) || (effect->type == SceneEffect::Tritone)) {
|
||||
GlProgram* program{};
|
||||
if (effect->type == SceneEffect::Fill) program = mPrograms[RT_EffectFill];
|
||||
else if (effect->type == SceneEffect::Tint) program = mPrograms[RT_EffectTint];
|
||||
else if (effect->type == SceneEffect::Tritone) program = mPrograms[RT_EffectTritone];
|
||||
else return false;
|
||||
// get current and intermidiate framebuffers
|
||||
auto dstFbo = pass->getFbo();
|
||||
auto dstCopyFbo = mBlendPool[0]->getRenderTarget(vp);
|
||||
// add uniform data
|
||||
auto params = (GlEffectParams*)(effect->rd);
|
||||
auto paramsOffset = mGpuBuffer.push(params, sizeof(GlEffectParams), true);
|
||||
// create gaussian blur tasks
|
||||
// create and setup task
|
||||
auto task = new GlEffectColorTransformTask(program, dstFbo, dstCopyFbo);
|
||||
task->setViewport({0, 0, vp.w, vp.h});
|
||||
task->addBindResource(GlBindingResource{0, program->getUniformBlockIndex("Params"), mGpuBuffer.getBufferId(), paramsOffset, sizeof(GlEffectParams)});
|
||||
|
|
|
@ -126,6 +126,7 @@ private:
|
|||
void effectGaussianBlurUpdate(RenderEffectGaussianBlur* effect, const Matrix& transform);
|
||||
void effectFillUpdate(RenderEffectFill* effect, const Matrix& transform);
|
||||
void effectTintUpdate(RenderEffectTint* effect, const Matrix& transform);
|
||||
void effectTritoneUpdate(RenderEffectTritone* effect, const Matrix& transform);
|
||||
|
||||
bool effectGaussianBlurRegion(RenderEffectGaussianBlur* effect);
|
||||
|
||||
|
|
|
@ -776,7 +776,7 @@ void main()
|
|||
|
||||
for (int y = -radius; y <= radius; ++y) {
|
||||
float weight = gaussian(float(y), sigma);
|
||||
vec2 offset = min(vec2(1.0), vec2(0.0, float(y) * texelSize.y));
|
||||
vec2 offset = vec2(0.0, float(y) * texelSize.y);
|
||||
colorSum += texture(uSrcTexture, vUV + offset) * weight;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
@ -812,8 +812,7 @@ void main()
|
|||
|
||||
for (int y = -radius; y <= radius; ++y) {
|
||||
float weight = gaussian(float(y), sigma);
|
||||
//vec2 offset = vec2(float(y) * texelSize.x, 0.0);
|
||||
vec2 offset = min(vec2(1.0), vec2(float(y) * texelSize.x, 0.0));
|
||||
vec2 offset = vec2(float(y) * texelSize.x, 0.0);
|
||||
colorSum += texture(uSrcTexture, vUV + offset) * weight;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
@ -858,3 +857,29 @@ void main()
|
|||
FragColor = mix(orig, mix(white, black, luma), intens) * orig.a;
|
||||
}
|
||||
)";
|
||||
|
||||
const char* EFFECT_TRITONE = R"(
|
||||
uniform sampler2D uSrcTexture;
|
||||
layout(std140) uniform Params {
|
||||
vec4 params[3];
|
||||
} uParams;
|
||||
|
||||
in vec2 vUV;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 orig = texture(uSrcTexture, vUV);
|
||||
float luma = dot(orig.rgb, vec3(0.2125, 0.7154, 0.0721));
|
||||
vec4 shadow = uParams.params[0];
|
||||
vec4 midtone = uParams.params[1];
|
||||
vec4 highlight = uParams.params[2];
|
||||
|
||||
FragColor = vec4(
|
||||
luma >= 0.5f ? mix(midtone.r, highlight.r, (luma - 0.5f)*2.0f) : mix(shadow.r, midtone.r, luma * 2.0f),
|
||||
luma >= 0.5f ? mix(midtone.g, highlight.g, (luma - 0.5f)*2.0f) : mix(shadow.g, midtone.g, luma * 2.0f),
|
||||
luma >= 0.5f ? mix(midtone.b, highlight.b, (luma - 0.5f)*2.0f) : mix(shadow.b, midtone.b, luma * 2.0f),
|
||||
luma >= 0.5f ? mix(midtone.a, highlight.a, (luma - 0.5f)*2.0f) : mix(shadow.a, midtone.a, luma * 2.0f)
|
||||
) * orig.a;
|
||||
}
|
||||
)";
|
||||
|
|
|
@ -59,5 +59,6 @@ extern const char* GAUSSIAN_VERTICAL;
|
|||
extern const char* GAUSSIAN_HORIZONTAL;
|
||||
extern const char* EFFECT_FILL;
|
||||
extern const char* EFFECT_TINT;
|
||||
extern const char* EFFECT_TRITONE;
|
||||
|
||||
#endif /* _TVG_GL_SHADERSRC_H_ */
|
||||
|
|
Loading…
Add table
Reference in a new issue