From 314167be4083f76c2b2951023d7f894e114bb30b Mon Sep 17 00:00:00 2001 From: ThomasWilshaw Date: Tue, 25 Jan 2022 23:13:32 +0000 Subject: [PATCH] Noise node (#1848) * Add a noise generator node * Cleanup * Correctly name CMakeLists.txt * Typo --- app/node/factory.cpp | 3 + app/node/factory.h | 1 + app/node/generator/CMakeLists.txt | 1 + app/node/generator/noise/CMakeLists.txt | 22 +++++++ app/node/generator/noise/noise.cpp | 82 +++++++++++++++++++++++++ app/node/generator/noise/noise.h | 53 ++++++++++++++++ app/shaders/noise.frag | 38 ++++++++++++ 7 files changed, 200 insertions(+) create mode 100644 app/node/generator/noise/CMakeLists.txt create mode 100644 app/node/generator/noise/noise.cpp create mode 100644 app/node/generator/noise/noise.h create mode 100644 app/shaders/noise.frag diff --git a/app/node/factory.cpp b/app/node/factory.cpp index 07e0fa3a3..ed2f15c78 100644 --- a/app/node/factory.cpp +++ b/app/node/factory.cpp @@ -33,6 +33,7 @@ #include "distort/transform/transformdistortnode.h" #include "effect/opacity/opacityeffect.h" #include "generator/matrix/matrix.h" +#include "generator/noise/noise.h" #include "generator/polygon/polygon.h" #include "generator/shape/shapenode.h" #include "generator/solid/solid.h" @@ -255,6 +256,8 @@ Node *NodeFactory::CreateFromFactoryIndex(const NodeFactory::InternalID &id) return new NodeGroup(); case kOpacityEffect: return new OpacityEffect(); + case kNoiseGenerator: + return new NoiseGeneratorNode(); case kInternalNodeCount: break; diff --git a/app/node/factory.h b/app/node/factory.h index c576f96a3..24da96373 100644 --- a/app/node/factory.h +++ b/app/node/factory.h @@ -63,6 +63,7 @@ public: kShapeGenerator, kGroupNode, kOpacityEffect, + kNoiseGenerator, // Count value kInternalNodeCount diff --git a/app/node/generator/CMakeLists.txt b/app/node/generator/CMakeLists.txt index dfdabb071..74432a826 100644 --- a/app/node/generator/CMakeLists.txt +++ b/app/node/generator/CMakeLists.txt @@ -15,6 +15,7 @@ # along with this program. If not, see . add_subdirectory(matrix) +add_subdirectory(noise) add_subdirectory(polygon) add_subdirectory(shape) add_subdirectory(solid) diff --git a/app/node/generator/noise/CMakeLists.txt b/app/node/generator/noise/CMakeLists.txt new file mode 100644 index 000000000..d883c2737 --- /dev/null +++ b/app/node/generator/noise/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/generator/noise/noise.h + node/generator/noise/noise.cpp + PARENT_SCOPE +) diff --git a/app/node/generator/noise/noise.cpp b/app/node/generator/noise/noise.cpp new file mode 100644 index 000000000..21eaa215e --- /dev/null +++ b/app/node/generator/noise/noise.cpp @@ -0,0 +1,82 @@ +/*** + + 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 . + +***/ + +#include "noise.h" + +namespace olive { + +const QString NoiseGeneratorNode::kColorInput = QStringLiteral("color_in"); +const QString NoiseGeneratorNode::kStrengthInput = QStringLiteral("strength_in"); + +NoiseGeneratorNode::NoiseGeneratorNode() +{ + AddInput(kStrengthInput, NodeValue::kFloat, 20); + + AddInput(kColorInput, NodeValue::kBoolean, false); +} + +Node* NoiseGeneratorNode::copy() const +{ + return new NoiseGeneratorNode(); +} + +QString NoiseGeneratorNode::Name() const +{ + return tr("Noise"); +} + +QString NoiseGeneratorNode::id() const +{ + return QStringLiteral("org.olivevideoeditor.Olive.noise"); +} + +QVector NoiseGeneratorNode::Category() const +{ + return {kCategoryGenerator}; +} + +QString NoiseGeneratorNode::Description() const +{ + return tr("Generates noise patterns"); +} + +void NoiseGeneratorNode::Retranslate() +{ + SetInputName(kStrengthInput, tr("Strength")); + SetInputName(kColorInput, tr("Color")); +} + +ShaderCode NoiseGeneratorNode::GetShaderCode(const QString& shader_id) const { + Q_UNUSED(shader_id) + return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/noise.frag")); +} + +void NoiseGeneratorNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const +{ + ShaderJob job; + + job.InsertValue(value); + job.InsertValue(QStringLiteral("time_in"), NodeValue(NodeValue::kFloat, globals.time().in().toDouble(), this)); + + + table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this); + +} +} diff --git a/app/node/generator/noise/noise.h b/app/node/generator/noise/noise.h new file mode 100644 index 000000000..31dfd2f3b --- /dev/null +++ b/app/node/generator/noise/noise.h @@ -0,0 +1,53 @@ +/*** + + 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 . + +***/ + +#ifndef NOISEGENERATORNODE_H +#define NOISEGENERATORNODE_H + +#include "node/node.h" + +namespace olive { + +class NoiseGeneratorNode : public Node { + Q_OBJECT + public: + NoiseGeneratorNode(); + + NODE_DEFAULT_DESTRUCTOR(NoiseGeneratorNode) + + 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 kColorInput; + static const QString kStrengthInput; +}; + +} // namespace olive + +#endif // NOISEGENERATORNODE_H diff --git a/app/shaders/noise.frag b/app/shaders/noise.frag new file mode 100644 index 000000000..377c87357 --- /dev/null +++ b/app/shaders/noise.frag @@ -0,0 +1,38 @@ +uniform float time_in; +varying vec2 ove_texcoord; + +uniform float strength_in; +uniform bool color_in; +//uniform bool blend; + +// precision lowp float; + +float PHI = 1.61803398874989484820459 * 00000.1; // Golden Ratio +float PI = 3.14159265358979323846264 * 00000.1; // PI +float SQ2 = 1.41421356237309504880169 * 10000.0; // Square Root of Two + +bool isNan( float val ) +{ + return ( val < 0.0 || 0.0 < val || val == 0.0 ) ? false : true; + // important: some nVidias failed to cope with version below. + // Probably wrong optimization. + /*return ( val <= 0.0 || 0.0 <= val ) ? false : true;*/ + + // Taken from: https://stackoverflow.com/questions/11810158/how-to-deal-with-nan-or-inf-in-opengl-es-2-0-shaders +} + +float gold_noise(vec2 coordinate, float seed){ + float value = fract(tan(distance(coordinate*(seed+PHI), vec2(PHI, PI)))*SQ2)*(strength_in*0.01); + return isNan(value) ? 0.0 : value; +} + +void main(void) { + vec3 noise; + if (color_in) { + noise = vec3(gold_noise(ove_texcoord, time_in + 42069.0), gold_noise(ove_texcoord, time_in + 69220.0), gold_noise(ove_texcoord, time_in + 1337.0)); + } else { + noise = vec3(gold_noise(ove_texcoord, time_in + 69420.0)); + } + + gl_FragColor = vec4(noise, 1.0); +}