diff --git a/app/node/effect/opacity/opacityeffect.cpp b/app/node/effect/opacity/opacityeffect.cpp index cc0f2d2c0..ee58fb632 100644 --- a/app/node/effect/opacity/opacityeffect.cpp +++ b/app/node/effect/opacity/opacityeffect.cpp @@ -39,15 +39,22 @@ void OpacityEffect::Retranslate() ShaderCode OpacityEffect::GetShaderCode(const ShaderRequest &request) const { - Q_UNUSED(request) - return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/opacity.frag")); + if (request.id == QStringLiteral("rgbmult")) { + return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/opacity_rgb.frag")); + } else { + return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/opacity.frag")); + } } void OpacityEffect::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const { // If there's no texture, no need to run an operation if (TexturePtr tex = value[kTextureInput].toTexture()) { - if (!qFuzzyCompare(value[kValueInput].toDouble(), 1.0)) { + if (TexturePtr opacity_tex = value[kValueInput].toTexture()) { + ShaderJob job(value); + job.SetShaderID(QStringLiteral("rgbmult")); + table->Push(NodeValue::kTexture, tex->toJob(job), this); + } else if (!qFuzzyCompare(value[kValueInput].toDouble(), 1.0)) { table->Push(NodeValue::kTexture, tex->toJob(ShaderJob(value)), this); } else { // 1.0 float is a no-op, so just push the texture diff --git a/app/shaders/opacity_rgb.frag b/app/shaders/opacity_rgb.frag new file mode 100644 index 000000000..6d529023e --- /dev/null +++ b/app/shaders/opacity_rgb.frag @@ -0,0 +1,27 @@ +// Inputs +uniform sampler2D tex_in; +uniform sampler2D opacity_in; + +// Input texture coordinate +in vec2 ove_texcoord; +out vec4 frag_color; + +vec3 rgb2hsv(vec3 c) +{ + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +void main() { + vec4 value = texture(opacity_in, ove_texcoord); + float v = rgb2hsv(value.rgb).b; + + vec4 c = texture(tex_in, ove_texcoord); + c *= v; + frag_color = c; +}