From 3aafb2466d6edf79bb8f42f1e5be025a52b72f0f Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 12 Apr 2022 13:05:45 -0700 Subject: [PATCH] Squashed commit of the following: commit f05b5b3ff8286f6252c2a3f3c8c367f8a5b821b5 Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue Apr 12 13:05:25 2022 -0700 final consistency modifications commit 4f27718d46de9660822eb197b0e900be947ec515 Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue Apr 12 11:40:58 2022 -0700 opengl: don't set texture options for null texture commit bb54cfcf4e219e1cbf1ecc6b5552cca75e6e1573 Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue Apr 12 11:40:29 2022 -0700 rename inputs commit e5ac8fffa2ac15f5549b6da5f42b05659c6d020f Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue Apr 12 10:37:23 2022 -0700 change alpha association formula commit dee09a88f17552e3f98be8940966822e45d6df4f Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue Apr 12 10:36:58 2022 -0700 glsl: use constants to improve readability commit aedc75ebee11b61198f29c464501a2ddb0506129 Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue Apr 12 10:36:26 2022 -0700 changed id capitalization commit 470b2bb85b51c4a57c109d3fb230088a81024277 Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue Apr 12 10:35:53 2022 -0700 node: update categories commit c78dacad82051dfbb3e40c92cfaf456dbff2de0d Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue Apr 12 09:22:57 2022 -0700 updated shaders to es 3 commit 1e7544be93e55916c94cd91629ec5eef728bfad8 Merge: 1bbb8d7f9 25d019609 Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue Apr 12 09:02:32 2022 -0700 Merge branch 'master' into pr/1818 commit 1bbb8d7f9acd75cb4498733f105fbe0487c0db9c Author: brimson <40442071+brimson@users.noreply.github.com> Date: Tue Jan 18 18:36:24 2022 -0700 Simplify colordifferencekey.frag Avoiding extra MOV instruction commit c7cf1021ce5a3d090833e94e4bc212cc51a61a2a Author: brimson <40442071+brimson@users.noreply.github.com> Date: Tue Jan 18 11:43:02 2022 -0700 Revert switch-case changes Thanks Simran, MattKC, and Wilshaw for the clarifications commit 882ffeede01b81f0cb4dfd885ba05bf66119ac7e Author: brimson <40442071+brimson@users.noreply.github.com> Date: Tue Jan 18 00:06:31 2022 -0700 Optimize despill shader Turn previous averaging from (1 MAD + 1 MUL) to (1 DP2), reuse the result to prevent recalculation. commit 0c93f519977fa34840ab03d51addcf2456f931d8 Author: Thomas Wilshaw Date: Sat Jan 8 17:23:49 2022 +0000 Cleanup commit 222560ce1a4666899b1111854d4d549dd7ba1357 Merge: 96e21c2b4 d3ffeaa35 Author: ThomasWilshaw Date: Tue Jan 4 23:50:39 2022 +0000 Merge branch 'master' into color_key commit 96e21c2b43db3bf1051aca696970509292159548 Author: Thomas Wilshaw Date: Tue Jan 4 23:45:26 2022 +0000 Rename and reoganise keying nodes commit 6d42ed23a69ebdb1f5b399957f0b37434d0519dd Author: Thomas Wilshaw Date: Tue Jan 4 23:04:50 2022 +0000 Move despill code to it's own node commit e97ab2e16fd1d4e2f2ff145b8c023ff0e1ee451e Author: Thomas Wilshaw Date: Mon Jan 3 21:39:48 2022 +0000 Add option for blue screens commit 2346f44e5af48bb9547c77c4c08ee7abfcb09393 Author: Thomas Wilshaw Date: Mon Jan 3 21:14:55 2022 +0000 Optimise node slightly commit 446522edcf63525fafe7a97cf6d59b7ea0385460 Author: Thomas Wilshaw Date: Mon Jan 3 21:10:03 2022 +0000 Fix GL ES compile error commit a765ce6c6f3e0c0e996f08e2a3ef1101818098e8 Author: Thomas Wilshaw Date: Sun Jan 2 18:27:24 2022 +0000 Cleanup commit d268e0645df34aa306dc391d1dc10bf335524f94 Author: Thomas Wilshaw Date: Sun Jan 2 18:03:26 2022 +0000 Fix core matte and change Darks start value commit 30b024dc5f59dd60ffc5012eee7a79201ed4f9c3 Author: Thomas Wilshaw Date: Sun Jan 2 17:26:39 2022 +0000 Change matte controls and cleanup commit b742a9ba7ed651785a0781289a4c03fd4fb72e03 Author: Thomas Wilshaw Date: Sun Jan 2 16:31:41 2022 +0000 Add a core and garbage matte commit f814d036b61b8de090df4c1f080c124b98b432d6 Author: Thomas Wilshaw Date: Sun Jan 2 03:31:20 2022 +0000 Improve basic keyer commit 4995ec3b9b92c9b4cb0dc31a247d585b2a47e408 Author: Thomas Wilshaw Date: Sun Jan 2 00:23:18 2022 +0000 Start simple color key node --- app/node/CMakeLists.txt | 1 + app/node/audio/pan/pan.cpp | 2 +- app/node/effect/opacity/opacityeffect.h | 2 +- app/node/factory.cpp | 6 ++ app/node/factory.h | 2 + app/node/group/group.cpp | 2 +- app/node/input/time/timeinput.cpp | 2 +- app/node/input/value/valuenode.h | 2 +- app/node/keying/CMakeLists.txt | 23 ++++ .../keying/colordifferencekey/CMakeLists.txt | 22 ++++ .../colordifferencekey/colordifferencekey.cpp | 101 ++++++++++++++++++ .../colordifferencekey/colordifferencekey.h | 51 +++++++++ app/node/keying/despill/CMakeLists.txt | 22 ++++ app/node/keying/despill/despill.cpp | 99 +++++++++++++++++ app/node/keying/despill/despill.h | 50 +++++++++ app/node/node.cpp | 14 +-- app/node/node.h | 7 +- app/node/time/timeoffset/timeoffsetnode.h | 2 +- app/node/time/timeremap/timeremap.cpp | 2 +- app/render/opengl/openglrenderer.cpp | 14 +-- app/shaders/colordifferencekey.frag | 68 ++++++++++++ app/shaders/despill.frag | 65 +++++++++++ 22 files changed, 531 insertions(+), 28 deletions(-) create mode 100644 app/node/keying/CMakeLists.txt create mode 100644 app/node/keying/colordifferencekey/CMakeLists.txt create mode 100644 app/node/keying/colordifferencekey/colordifferencekey.cpp create mode 100644 app/node/keying/colordifferencekey/colordifferencekey.h create mode 100644 app/node/keying/despill/CMakeLists.txt create mode 100644 app/node/keying/despill/despill.cpp create mode 100644 app/node/keying/despill/despill.h create mode 100644 app/shaders/colordifferencekey.frag create mode 100644 app/shaders/despill.frag diff --git a/app/node/CMakeLists.txt b/app/node/CMakeLists.txt index aa1a090d4..cd510b021 100644 --- a/app/node/CMakeLists.txt +++ b/app/node/CMakeLists.txt @@ -24,6 +24,7 @@ add_subdirectory(generator) add_subdirectory(gizmo) add_subdirectory(group) add_subdirectory(input) +add_subdirectory(keying) add_subdirectory(math) add_subdirectory(output) add_subdirectory(project) diff --git a/app/node/audio/pan/pan.cpp b/app/node/audio/pan/pan.cpp index 457c4cdd1..9eb8e0766 100644 --- a/app/node/audio/pan/pan.cpp +++ b/app/node/audio/pan/pan.cpp @@ -54,7 +54,7 @@ QString PanNode::id() const QVector PanNode::Category() const { - return {kCategoryChannels}; + return {kCategoryFilter}; } QString PanNode::Description() const diff --git a/app/node/effect/opacity/opacityeffect.h b/app/node/effect/opacity/opacityeffect.h index ac699a813..d18af81cc 100644 --- a/app/node/effect/opacity/opacityeffect.h +++ b/app/node/effect/opacity/opacityeffect.h @@ -26,7 +26,7 @@ public: virtual QVector Category() const override { - return {kCategoryFilter, kCategoryVideoEffect}; + return {kCategoryFilter}; } virtual QString Description() const override diff --git a/app/node/factory.cpp b/app/node/factory.cpp index 990438eac..3f32fe17a 100644 --- a/app/node/factory.cpp +++ b/app/node/factory.cpp @@ -50,6 +50,8 @@ #include "math/math/math.h" #include "math/merge/merge.h" #include "math/trigonometry/trigonometry.h" +#include "keying/colordifferencekey/colordifferencekey.h" +#include "keying/despill/despill.h" #include "output/track/track.h" #include "output/viewer/viewer.h" #include "project/folder/folder.h" @@ -259,6 +261,10 @@ Node *NodeFactory::CreateFromFactoryIndex(const NodeFactory::InternalID &id) return new SubtitleBlock(); case kShapeGenerator: return new ShapeNode(); + case kColorDifferenceKeyKeying: + return new ColorDifferenceKeyNode(); + case kDespillKeying: + return new DespillNode(); case kGroupNode: return new NodeGroup(); case kOpacityEffect: diff --git a/app/node/factory.h b/app/node/factory.h index 5d76b6b47..0a461892f 100644 --- a/app/node/factory.h +++ b/app/node/factory.h @@ -62,6 +62,8 @@ public: kTimeRemapNode, kSubtitleBlock, kShapeGenerator, + kColorDifferenceKeyKeying, + kDespillKeying, kGroupNode, kOpacityEffect, kFlipDistort, diff --git a/app/node/group/group.cpp b/app/node/group/group.cpp index b6f194032..793140c8a 100644 --- a/app/node/group/group.cpp +++ b/app/node/group/group.cpp @@ -43,7 +43,7 @@ QString NodeGroup::id() const QVector NodeGroup::Category() const { - return {kCategoryGeneral}; + return {kCategoryUnknown}; } QString NodeGroup::Description() const diff --git a/app/node/input/time/timeinput.cpp b/app/node/input/time/timeinput.cpp index b26f101d7..96f80f385 100644 --- a/app/node/input/time/timeinput.cpp +++ b/app/node/input/time/timeinput.cpp @@ -45,7 +45,7 @@ QString TimeInput::id() const QVector TimeInput::Category() const { - return {kCategoryInput}; + return {kCategoryTime}; } QString TimeInput::Description() const diff --git a/app/node/input/value/valuenode.h b/app/node/input/value/valuenode.h index f6205fbd8..2d6d2ada8 100644 --- a/app/node/input/value/valuenode.h +++ b/app/node/input/value/valuenode.h @@ -50,7 +50,7 @@ public: virtual QVector Category() const override { - return {kCategoryInput}; + return {kCategoryGenerator}; } virtual QString Description() const override diff --git a/app/node/keying/CMakeLists.txt b/app/node/keying/CMakeLists.txt new file mode 100644 index 000000000..2177a550a --- /dev/null +++ b/app/node/keying/CMakeLists.txt @@ -0,0 +1,23 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2021 Olive Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +add_subdirectory(colordifferencekey) +add_subdirectory(despill) + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + PARENT_SCOPE +) diff --git a/app/node/keying/colordifferencekey/CMakeLists.txt b/app/node/keying/colordifferencekey/CMakeLists.txt new file mode 100644 index 000000000..66422f411 --- /dev/null +++ b/app/node/keying/colordifferencekey/CMakeLists.txt @@ -0,0 +1,22 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2021 Olive Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + node/keying/colordifferencekey/colordifferencekey.h + node/keying/colordifferencekey/colordifferencekey.cpp + PARENT_SCOPE +) diff --git a/app/node/keying/colordifferencekey/colordifferencekey.cpp b/app/node/keying/colordifferencekey/colordifferencekey.cpp new file mode 100644 index 000000000..1f2ca4d1c --- /dev/null +++ b/app/node/keying/colordifferencekey/colordifferencekey.cpp @@ -0,0 +1,101 @@ +/*** + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +***/ + +#include "colordifferencekey.h" + +namespace olive { + +const QString ColorDifferenceKeyNode::kTextureInput = QStringLiteral("tex_in"); +const QString ColorDifferenceKeyNode::kGarbageMatteInput = QStringLiteral("garbage_in"); +const QString ColorDifferenceKeyNode::kCoreMatteInput = QStringLiteral("core_in"); +const QString ColorDifferenceKeyNode::kColorInput = QStringLiteral("color_in"); +const QString ColorDifferenceKeyNode::kShadowsInput = QStringLiteral("shadows_in"); +const QString ColorDifferenceKeyNode::kHighlightsInput = QStringLiteral("highlights_in"); +const QString ColorDifferenceKeyNode::kMaskOnlyInput = QStringLiteral("mask_only_in"); + +ColorDifferenceKeyNode::ColorDifferenceKeyNode() { + AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); + + AddInput(kGarbageMatteInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); + + AddInput(kCoreMatteInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); + + AddInput(kColorInput, NodeValue::kCombo, 0); + + AddInput(kHighlightsInput, NodeValue::kFloat, 100.0f); + SetInputProperty(kHighlightsInput, QStringLiteral("min"), 0.0); + + AddInput(kShadowsInput, NodeValue::kFloat, 100.0f); + SetInputProperty(kShadowsInput, QStringLiteral("min"), 0.0); + + AddInput(kMaskOnlyInput, NodeValue::kBoolean, false); +} + +Node *ColorDifferenceKeyNode::copy() const +{ + return new ColorDifferenceKeyNode(); +} + +QString ColorDifferenceKeyNode::Name() const +{ + return tr("Color Difference Key"); +} + +QString ColorDifferenceKeyNode::id() const +{ + return QStringLiteral("org.olivevideoeditor.Olive.colordifferencekey"); +} + +QVector ColorDifferenceKeyNode::Category() const +{ + return {kCategoryKeying}; +} + +QString ColorDifferenceKeyNode::Description() const +{ + return tr("A simple color key based on the distance of one color from other colors."); +} + +void ColorDifferenceKeyNode::Retranslate() +{ + SetInputName(kTextureInput, tr("Input")); + SetInputName(kGarbageMatteInput, tr("Garbage Matte")); + SetInputName(kCoreMatteInput, tr("Core Matte")); + SetInputName(kColorInput, tr("Key Color")); + SetComboBoxStrings(kColorInput, {tr("Green"), tr("Blue")}); + SetInputName(kShadowsInput, tr("Shadows")); + SetInputName(kHighlightsInput, tr("Highlights")); + SetInputName(kMaskOnlyInput, tr("Show Mask Only")); +} + +ShaderCode ColorDifferenceKeyNode::GetShaderCode(const QString &shader_id) const +{ + Q_UNUSED(shader_id) + return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/colordifferencekey.frag")); +} + +void ColorDifferenceKeyNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const +{ + ShaderJob job; + job.InsertValue(value); + job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn); + + // If there's no texture, no need to run an operation + if (!job.GetValue(kTextureInput).data().isNull()) { + table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this); + } +} + +} // namespace olive diff --git a/app/node/keying/colordifferencekey/colordifferencekey.h b/app/node/keying/colordifferencekey/colordifferencekey.h new file mode 100644 index 000000000..01ddaf718 --- /dev/null +++ b/app/node/keying/colordifferencekey/colordifferencekey.h @@ -0,0 +1,51 @@ +/*** + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +***/ + +#ifndef COLORDIFFERENCEKEYNODE_H +#define COLORDIFFERENCEKEYNODE_H + +#include "node/node.h" + +namespace olive { + +class ColorDifferenceKeyNode : public Node { + public: + ColorDifferenceKeyNode(); + + virtual Node* copy() const override; + + virtual QString Name() const override; + virtual QString id() const override; + virtual QVector Category() const override; + virtual QString Description() const override; + + virtual void Retranslate() override; + + virtual ShaderCode GetShaderCode(const QString& shader_id) const override; + virtual void Value(const NodeValueRow& value, const NodeGlobals& globals, NodeValueTable* table) const override; + + static const QString kTextureInput; + static const QString kGarbageMatteInput; + static const QString kCoreMatteInput; + static const QString kColorInput; + static const QString kShadowsInput; + static const QString kHighlightsInput; + static const QString kMaskOnlyInput; + +}; + +} // namespace olive + +#endif // COLORDIFFERENCEKEYNODE_H diff --git a/app/node/keying/despill/CMakeLists.txt b/app/node/keying/despill/CMakeLists.txt new file mode 100644 index 000000000..69ee377d6 --- /dev/null +++ b/app/node/keying/despill/CMakeLists.txt @@ -0,0 +1,22 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2021 Olive Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + node/keying/despill/despill.h + node/keying/despill/despill.cpp + PARENT_SCOPE +) diff --git a/app/node/keying/despill/despill.cpp b/app/node/keying/despill/despill.cpp new file mode 100644 index 000000000..147ee60df --- /dev/null +++ b/app/node/keying/despill/despill.cpp @@ -0,0 +1,99 @@ +/*** + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +***/ + +#include "despill.h" + +#include "node/project/project.h" + +namespace olive { + +const QString DespillNode::kTextureInput = QStringLiteral("tex_in"); +const QString DespillNode::kColorInput = QStringLiteral("color_in"); +const QString DespillNode::kMethodInput = QStringLiteral("method_in"); +const QString DespillNode::kPreserveLuminanceInput = QStringLiteral("preserve_luminance_input"); + +DespillNode::DespillNode() +{ + AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); + + AddInput(kColorInput, NodeValue::kCombo, 0); + + AddInput(kMethodInput, NodeValue::kCombo, 0); + + AddInput(kPreserveLuminanceInput, NodeValue::kBoolean, false); +} + +Node* DespillNode::copy() const +{ + return new DespillNode(); +} + +QString DespillNode::Name() const +{ + return tr("Despill"); +} + +QString DespillNode::id() const +{ + return QStringLiteral("org.olivevideoeditor.Olive.despill"); +} + +QVector DespillNode::Category() const +{ + return {kCategoryKeying}; +} + +QString DespillNode::Description() const +{ + return tr("Selection of simple depsill operations"); +} + +void DespillNode::Retranslate() +{ + SetInputName(kTextureInput, tr("Input")); + + SetInputName(kColorInput, tr("Key Color")); + SetComboBoxStrings(kColorInput, {tr("Green"), tr("Blue")}); + + + SetInputName(kMethodInput, tr("Method")); + SetComboBoxStrings(kMethodInput, {tr("Average"), tr("Double Red Average"), tr("Double Average"), tr("Limit")}); + + SetInputName(kPreserveLuminanceInput, tr("Preserve Luminance")); +} + +ShaderCode DespillNode::GetShaderCode(const QString& shader_id) const { + Q_UNUSED(shader_id) + return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/despill.frag")); +} + +void DespillNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const { + ShaderJob job; + job.InsertValue(value); + + // Set luma coefficients + double luma_coeffs[3] = {0.0f, 0.0f, 0.0f}; + project()->color_manager()->GetDefaultLumaCoefs(luma_coeffs); + job.InsertValue(QStringLiteral("luma_coeffs"), + NodeValue(NodeValue::kVec3, QVector3D(luma_coeffs[0], luma_coeffs[1], luma_coeffs[2]))); + + // If there's no texture, no need to run an operation + if (!job.GetValue(kTextureInput).data().isNull()) { + table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this); + } +} + + +} // namespace olive diff --git a/app/node/keying/despill/despill.h b/app/node/keying/despill/despill.h new file mode 100644 index 000000000..c5aaed49d --- /dev/null +++ b/app/node/keying/despill/despill.h @@ -0,0 +1,50 @@ +/*** + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +***/ + +#ifndef DESPILLNODE_H +#define DESPILLNODE_H + +#include "node/node.h" +#include "node/color/colormanager/colormanager.h" + +namespace olive { + +class DespillNode : public Node { + public: + DespillNode(); + + virtual Node* copy() const override; + + virtual QString Name() const override; + virtual QString id() const override; + virtual QVector Category() const override; + virtual QString Description() const override; + + virtual void Retranslate() override; + + virtual ShaderCode GetShaderCode(const QString& shader_id) const override; + virtual void Value(const NodeValueRow& value, const NodeGlobals& globals, NodeValueTable* table) const override; + + static const QString kTextureInput; + static const QString kColorInput; + static const QString kMethodInput; + static const QString kPreserveLuminanceInput; + + +}; + +} // namespace olive + +#endif // DESPILLNODE_H diff --git a/app/node/node.cpp b/app/node/node.cpp index 506e4044e..c8afb1f12 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -1668,16 +1668,14 @@ void Node::DisconnectAll() QString Node::GetCategoryName(const CategoryID &c) { switch (c) { - case kCategoryInput: - return tr("Input"); case kCategoryOutput: return tr("Output"); - case kCategoryGeneral: - return tr("General"); case kCategoryDistort: return tr("Distort"); case kCategoryMath: return tr("Math"); + case kCategoryKeying: + return tr("Keying"); case kCategoryColor: return tr("Color"); case kCategoryFilter: @@ -1686,16 +1684,12 @@ QString Node::GetCategoryName(const CategoryID &c) return tr("Timeline"); case kCategoryGenerator: return tr("Generator"); - case kCategoryChannels: - return tr("Channel"); case kCategoryTransition: return tr("Transition"); case kCategoryProject: return tr("Project"); - case kCategoryVideoEffect: - return tr("Video Effect"); - case kCategoryAudioEffect: - return tr("Audio Effect"); + case kCategoryTime: + return tr("Time"); case kCategoryUnknown: case kCategoryCount: break; diff --git a/app/node/node.h b/app/node/node.h index 44d704344..6d2c27144 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -78,20 +78,17 @@ public: enum CategoryID { kCategoryUnknown = -1, - kCategoryInput, kCategoryOutput, kCategoryGenerator, kCategoryMath, + kCategoryKeying, kCategoryFilter, kCategoryColor, - kCategoryGeneral, + kCategoryTime, kCategoryTimeline, - kCategoryChannels, kCategoryTransition, kCategoryDistort, kCategoryProject, - kCategoryVideoEffect, - kCategoryAudioEffect, kCategoryCount }; diff --git a/app/node/time/timeoffset/timeoffsetnode.h b/app/node/time/timeoffset/timeoffsetnode.h index aa712891f..b44a1f1e0 100644 --- a/app/node/time/timeoffset/timeoffsetnode.h +++ b/app/node/time/timeoffset/timeoffsetnode.h @@ -45,7 +45,7 @@ public: virtual QVector Category() const override { - return {kCategoryGeneral}; + return {kCategoryTime}; } virtual QString Description() const override diff --git a/app/node/time/timeremap/timeremap.cpp b/app/node/time/timeremap/timeremap.cpp index 8967faad9..1f52a27c4 100644 --- a/app/node/time/timeremap/timeremap.cpp +++ b/app/node/time/timeremap/timeremap.cpp @@ -56,7 +56,7 @@ QString TimeRemapNode::id() const QVector TimeRemapNode::Category() const { - return {kCategoryGeneral}; + return {kCategoryTime}; } QString TimeRemapNode::Description() const diff --git a/app/render/opengl/openglrenderer.cpp b/app/render/opengl/openglrenderer.cpp index 810b022e6..8d9786973 100644 --- a/app/render/opengl/openglrenderer.cpp +++ b/app/render/opengl/openglrenderer.cpp @@ -540,13 +540,15 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video GLenum target = (texture && texture->type() == Texture::k3D) ? GL_TEXTURE_3D : GL_TEXTURE_2D; functions_->glBindTexture(target, tex_id); - PrepareInputTexture(target, t.interpolation); + if (tex_id) { + PrepareInputTexture(target, t.interpolation); - if (texture && texture->channel_count() == 1 && destination_params.channel_count() != 1) { - // Interpret this texture as a grayscale texture - functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED); - functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED); - functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + if (texture->channel_count() == 1 && destination_params.channel_count() != 1) { + // Interpret this texture as a grayscale texture + functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED); + functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED); + functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + } } } diff --git a/app/shaders/colordifferencekey.frag b/app/shaders/colordifferencekey.frag new file mode 100644 index 000000000..5ed5fb9ec --- /dev/null +++ b/app/shaders/colordifferencekey.frag @@ -0,0 +1,68 @@ +uniform sampler2D tex_in; +uniform sampler2D garbage_in; +uniform sampler2D core_in; +uniform int color_in; +uniform bool garbage_in_enabled; +uniform bool core_in_enabled; +uniform float highlights_in; +uniform float shadows_in; +uniform bool mask_only_in; + +in vec2 ove_texcoord; +out vec4 frag_color; + +#define SCREEN_COLOR_GREEN 0 +#define SCREEN_COLOR_BLUE 1 + +void main(void) { + vec4 tex_col = texture(tex_in, ove_texcoord); + + // Unassociate RGB before calculating values + vec4 unassoc = tex_col; + if (unassoc.a > 0) { + unassoc.rgb /= unassoc.a; + } + + // Simple keyer, generates a inverted mask (background is white, foreground black) + float mask; + if (color_in == SCREEN_COLOR_GREEN) { + mask = (unassoc.g - max(unassoc.r, unassoc.b)); + } else{ // Assume SCREEN_COLOR_BLUE + mask = (unassoc.b - max(unassoc.r, unassoc.g)); + } + + mask = clamp(mask, 0.0, 1.0); + + if (garbage_in_enabled) { + // Force anything we want to remove to be 1.0 + vec4 garbage = texture(garbage_in, ove_texcoord); + // Assumes garbage is achromatic + mask += garbage.r; + mask = clamp(mask, 0.0, 1.0); + } + + if (core_in_enabled) { + // Force anything we want to keep to be 0.1 + vec3 core = texture(core_in, ove_texcoord).rgb; + vec3 core_invert = 1.0 - core.rgb; + // Assumes core is achromatic + mask *= core_invert.r; + mask = clamp(mask, 0.0, 1.0); + } + + // Crush blacks and push whites + mask = highlights_in * 0.01 * (shadows_in * 0.01 * mask - 1.0) + 1.0; + mask = clamp(mask, 0.0, 1.0); + + // Invert mask + mask = 1.0 - mask; + + // Multiply color by mask + tex_col *= mask; + + if (!mask_only_in) { + frag_color = tex_col; + } else { + frag_color = vec4(vec3(mask), 1.0); + } +} diff --git a/app/shaders/despill.frag b/app/shaders/despill.frag new file mode 100644 index 000000000..6753c0d27 --- /dev/null +++ b/app/shaders/despill.frag @@ -0,0 +1,65 @@ +uniform sampler2D tex_in; +uniform int color_in; +uniform int method_in; +uniform bool preserve_luminance_input; +uniform vec3 luma_coeffs; + +in vec2 ove_texcoord; +out vec4 frag_color; + +#define AVERAGE 0 +#define DOUBLE_RED_AVERAGE 1 +#define DOUBLE_AVERAGE 2 +#define BLUE_LIMIT 3 + +void main(void) { + vec4 original_col = texture(tex_in, ove_texcoord); + vec4 tex_col = original_col; + float color_average = 0.0; + + if(color_in == 0) { // Green screen + switch (method_in) { + case AVERAGE: + color_average = dot(tex_col.rb, vec2(0.5)); // (tex_col.r + tex_col.b) / 2.0 + tex_col.g = tex_col.g > color_average ? color_average: tex_col.g; + break; + case DOUBLE_RED_AVERAGE: + color_average = dot(tex_col.rb, vec2(2.0, 1.0) / 3.0); // (2.0 * tex_col.r + tex_col.b) / 3.0 + tex_col.g = tex_col.g > color_average ? color_average : tex_col.g; + break; + case DOUBLE_AVERAGE: + color_average = dot(tex_col.br, vec2(2.0, 1.0) / 3.0); // (2.0 * tex_col.b + tex_col.r) / 3.0 + tex_col.g = tex_col.g > color_average ? color_average : tex_col.g; + break; + case BLUE_LIMIT: + tex_col.g = tex_col.g > tex_col.b ? tex_col.b : tex_col.g; + break; + } + } else { // Blue screen + switch (method_in) { + case AVERAGE: + color_average = dot(tex_col.rg, vec2(0.5)); // (tex_col.r + tex_col.g) / 2.0 + tex_col.b = tex_col.b > color_average ? color_average : tex_col.b; + break; + case DOUBLE_RED_AVERAGE: + color_average = dot(tex_col.rg, vec2(2.0, 1.0) / 3.0); // (2.0 * tex_col.r + tex_col.g) / 3.0 + tex_col.b = tex_col.b > color_average ? color_average : tex_col.b; + break; + case DOUBLE_AVERAGE: + color_average = dot(tex_col.gr, vec2(2.0, 1.0) / 3.0); // (2.0 * tex_col.g+ tex_col.r) / 3.0 + tex_col.b = tex_col.b > color_average ? color_average : tex_col.b; + break; + case BLUE_LIMIT: + tex_col.b = tex_col.b > tex_col.g ? tex_col.g : tex_col.b; + break; + } + } + + if (preserve_luminance_input) { + vec4 diff = original_col - tex_col; + float luma = dot(abs(diff.rgb), luma_coeffs); + tex_col.rgb += vec3(luma); + } + + frag_color = tex_col; +}