diff --git a/app/node/CMakeLists.txt b/app/node/CMakeLists.txt
index 508bf00bf..c97d250ca 100644
--- a/app/node/CMakeLists.txt
+++ b/app/node/CMakeLists.txt
@@ -18,6 +18,7 @@ add_subdirectory(audio)
add_subdirectory(block)
add_subdirectory(color)
add_subdirectory(distort)
+add_subdirectory(effect)
add_subdirectory(filter)
add_subdirectory(generator)
add_subdirectory(group)
diff --git a/app/node/effect/CMakeLists.txt b/app/node/effect/CMakeLists.txt
new file mode 100644
index 000000000..e5bdb09ae
--- /dev/null
+++ b/app/node/effect/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 .
+
+add_subdirectory(opacity)
+
+set(OLIVE_SOURCES
+ ${OLIVE_SOURCES}
+ PARENT_SCOPE
+)
diff --git a/app/node/effect/opacity/CMakeLists.txt b/app/node/effect/opacity/CMakeLists.txt
new file mode 100644
index 000000000..677fe38e0
--- /dev/null
+++ b/app/node/effect/opacity/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/effect/opacity/opacityeffect.cpp
+ node/effect/opacity/opacityeffect.h
+ PARENT_SCOPE
+)
diff --git a/app/node/effect/opacity/opacityeffect.cpp b/app/node/effect/opacity/opacityeffect.cpp
new file mode 100644
index 000000000..7c904c6ad
--- /dev/null
+++ b/app/node/effect/opacity/opacityeffect.cpp
@@ -0,0 +1,38 @@
+#include "opacityeffect.h"
+
+#include "node/math/math/math.h"
+#include "widget/slider/floatslider.h"
+
+namespace olive {
+
+#define super NodeGroup
+
+OpacityEffect::OpacityEffect()
+{
+ MathNode *math = new MathNode();
+
+ math->SetOperation(MathNode::kOpMultiply);
+
+ SetNodePositionInContext(math, QPointF(0, 0));
+
+ tex_in_pass_ = AddInputPassthrough(NodeInput(math, MathNode::kParamAIn));
+ SetInputDataType(tex_in_pass_, NodeValue::kTexture);
+
+ value_in_pass_ = AddInputPassthrough(NodeInput(math, MathNode::kParamBIn));
+ SetInputProperty(value_in_pass_, QStringLiteral("view"), FloatSlider::kPercentage);
+ SetInputProperty(value_in_pass_, QStringLiteral("min"), 0.0);
+ SetInputProperty(value_in_pass_, QStringLiteral("max"), 1.0);
+ math->SetStandardValue(MathNode::kParamBIn, 1.0);
+
+ SetOutputPassthrough(math);
+}
+
+void OpacityEffect::Retranslate()
+{
+ super::Retranslate();
+
+ SetInputName(tex_in_pass_, tr("Texture"));
+ SetInputName(value_in_pass_, tr("Opacity"));
+}
+
+}
diff --git a/app/node/effect/opacity/opacityeffect.h b/app/node/effect/opacity/opacityeffect.h
new file mode 100644
index 000000000..82e1f16f6
--- /dev/null
+++ b/app/node/effect/opacity/opacityeffect.h
@@ -0,0 +1,47 @@
+#ifndef OPACITYEFFECT_H
+#define OPACITYEFFECT_H
+
+#include "node/group/group.h"
+
+namespace olive {
+
+class OpacityEffect : public NodeGroup
+{
+public:
+ OpacityEffect();
+
+ NODE_DEFAULT_DESTRUCTOR(OpacityEffect)
+
+ NODE_COPY_FUNCTION(OpacityEffect)
+
+ virtual QString Name() const override
+ {
+ return tr("Opacity");
+ }
+
+ virtual QString id() const override
+ {
+ return QStringLiteral("org.olivevideoeditor.Olive.opacityeffect");
+ }
+
+ virtual QVector Category() const override
+ {
+ return {kCategoryFilter, kCategoryVideoEffect};
+ }
+
+ virtual QString Description() const override
+ {
+ return tr("Alter a video's opacity.\n\nThis is equivalent to multiplying a video by a number between 0.0 and 1.0.");
+ }
+
+ virtual void Retranslate() override;
+
+private:
+ QString tex_in_pass_;
+ QString value_in_pass_;
+
+};
+
+}
+
+#endif // OPACITYEFFECT_H
diff --git a/app/node/factory.cpp b/app/node/factory.cpp
index 447ba0dbd..07e0fa3a3 100644
--- a/app/node/factory.cpp
+++ b/app/node/factory.cpp
@@ -31,6 +31,7 @@
#include "block/transition/diptocolor/diptocolortransition.h"
#include "distort/crop/cropdistortnode.h"
#include "distort/transform/transformdistortnode.h"
+#include "effect/opacity/opacityeffect.h"
#include "generator/matrix/matrix.h"
#include "generator/polygon/polygon.h"
#include "generator/shape/shapenode.h"
@@ -252,6 +253,8 @@ Node *NodeFactory::CreateFromFactoryIndex(const NodeFactory::InternalID &id)
return new ShapeNode();
case kGroupNode:
return new NodeGroup();
+ case kOpacityEffect:
+ return new OpacityEffect();
case kInternalNodeCount:
break;
diff --git a/app/node/factory.h b/app/node/factory.h
index 10101e648..c576f96a3 100644
--- a/app/node/factory.h
+++ b/app/node/factory.h
@@ -62,6 +62,7 @@ public:
kSubtitleBlock,
kShapeGenerator,
kGroupNode,
+ kOpacityEffect,
// Count value
kInternalNodeCount
diff --git a/app/node/node.cpp b/app/node/node.cpp
index 23040265c..d2ad25f30 100644
--- a/app/node/node.cpp
+++ b/app/node/node.cpp
@@ -1643,6 +1643,10 @@ QString Node::GetCategoryName(const CategoryID &c)
return tr("Transition");
case kCategoryProject:
return tr("Project");
+ case kCategoryVideoEffect:
+ return tr("Video Effect");
+ case kCategoryAudioEffect:
+ return tr("Audio Effect");
case kCategoryUnknown:
case kCategoryCount:
break;
diff --git a/app/node/node.h b/app/node/node.h
index 8f89666b8..cd168d84f 100644
--- a/app/node/node.h
+++ b/app/node/node.h
@@ -90,6 +90,8 @@ public:
kCategoryTransition,
kCategoryDistort,
kCategoryProject,
+ kCategoryVideoEffect,
+ kCategoryAudioEffect,
kCategoryCount
};