Add afterglow effect

pull/281/head
James H Ball 2025-02-02 13:46:27 +00:00
rodzic 200fc1775a
commit 476a359be8
8 zmienionych plików z 81 dodań i 3 usunięć

Wyświetl plik

@ -0,0 +1,21 @@
std::string afterglowFragmentShader = R"(
uniform sampler2D uTexture0;
varying vec2 vTexCoord;
uniform float fadeAmount;
uniform float afterglowAmount;
// tanh is not available in GLSL ES 1.0, so we define it here.
float hypTan(float x) {
return (exp(x) - exp(-x)) / (exp(x) + exp(-x));
}
void main() {
vec4 line = texture2D(uTexture0, vTexCoord);
float fade = fadeAmount * hypTan(min(line.r / afterglowAmount, 10.0));
fade = clamp(fade, 0.0, fadeAmount);
gl_FragColor = vec4(0.0, 0.0, 0.0, fade);
}
)";

Wyświetl plik

@ -0,0 +1,11 @@
std::string afterglowVertexShader = R"(
attribute vec2 aPos;
varying vec2 vTexCoord;
void main() {
gl_Position = vec4(aPos, 0.0, 1.0);
vTexCoord = (0.5 * aPos + 0.5);
}
)";

Wyświetl plik

@ -2,6 +2,8 @@
#include "VisualiserComponent.h"
#include "../CommonPluginProcessor.h"
#include "AfterglowFragmentShader.glsl"
#include "AfterglowVertexShader.glsl"
#include "BlurFragmentShader.glsl"
#include "BlurVertexShader.glsl"
#include "WideBlurFragmentShader.glsl"
@ -674,6 +676,11 @@ void VisualiserComponent::newOpenGLContextCreated() {
glowShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(glowVertexShader));
glowShader->addFragmentShader(glowFragmentShader);
glowShader->link();
afterglowShader = std::make_unique<juce::OpenGLShaderProgram>(openGLContext);
afterglowShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(afterglowVertexShader));
afterglowShader->addFragmentShader(afterglowFragmentShader);
afterglowShader->link();
#endif
glGenBuffers(1, &vertexBuffer);
@ -706,6 +713,7 @@ void VisualiserComponent::openGLContextClosing() {
glDeleteTextures(1, &glowTexture.id);
reflectionOpenGLTexture.release();
glowShader.reset();
afterglowShader.reset();
#endif
simpleShader.reset();
@ -1093,6 +1101,13 @@ void VisualiserComponent::fade() {
setNormalBlending();
#if SOSCI_FEATURES
setShader(afterglowShader.get());
afterglowShader->setUniform("fadeAmount", fadeAmount);
afterglowShader->setUniform("afterglowAmount", (float) settings.getAfterglow());
afterglowShader->setUniform("uResizeForCanvas", lineTexture.width / (float) recordingSettings.getResolution());
drawTexture({lineTexture});
#else
simpleShader->use();
glEnableVertexAttribArray(glGetAttribLocation(simpleShader->getProgramID(), "vertexPosition"));
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
@ -1103,6 +1118,7 @@ void VisualiserComponent::fade() {
simpleShader->setUniform("colour", 0.0f, 0.0f, 0.0f, fadeAmount);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(glGetAttribLocation(simpleShader->getProgramID(), "vertexPosition"));
#endif
}
void VisualiserComponent::drawCRT() {

Wyświetl plik

@ -228,6 +228,7 @@ private:
Texture reflectionTexture;
std::unique_ptr<juce::OpenGLShaderProgram> glowShader;
std::unique_ptr<juce::OpenGLShaderProgram> afterglowShader;
#endif
std::unique_ptr<juce::OpenGLShaderProgram> simpleShader;

Wyświetl plik

@ -20,6 +20,7 @@ VisualiserSettings::VisualiserSettings(VisualiserParameters& p, int numChannels)
addAndMakeVisible(screenOverlayLabel);
addAndMakeVisible(screenOverlay);
#if SOSCI_FEATURES
addAndMakeVisible(afterglow);
addAndMakeVisible(screenSaturation);
addAndMakeVisible(stereo);
addAndMakeVisible(xOffset);
@ -62,6 +63,7 @@ VisualiserSettings::VisualiserSettings(VisualiserParameters& p, int numChannels)
};
#if SOSCI_FEATURES
afterglow.setSliderOnValueChange();
screenSaturation.setSliderOnValueChange();
stereo.setSliderOnValueChange();
xOffset.setSliderOnValueChange();
@ -92,6 +94,9 @@ void VisualiserSettings::resized() {
intensity.setBounds(area.removeFromTop(rowHeight));
persistence.setBounds(area.removeFromTop(rowHeight));
#if SOSCI_FEATURES
afterglow.setBounds(area.removeFromTop(rowHeight));
#endif
hue.setBounds(area.removeFromTop(rowHeight));
lineSaturation.setBounds(area.removeFromTop(rowHeight));
#if SOSCI_FEATURES

Wyświetl plik

@ -106,6 +106,14 @@ public:
VERSION_HINT, 1.0, 0.0, 5.0
)
);
std::shared_ptr<Effect> afterglowEffect = std::make_shared<Effect>(
new EffectParameter(
"Afterglow",
"Controls how quickly the image disappears after glowing brightly. Closely related to persistence.",
"afterglow",
VERSION_HINT, 2.0, 0.0, 5.0
)
);
std::shared_ptr<StereoEffect> stereoEffectApplication = std::make_shared<StereoEffect>();
std::shared_ptr<Effect> stereoEffect = std::make_shared<Effect>(
stereoEffectApplication,
@ -255,11 +263,14 @@ public:
ambientEffect,
sweepMsEffect,
triggerValueEffect,
#if SOSCI_FEATURES
afterglowEffect,
screenSaturationEffect,
#endif
};
std::vector<std::shared_ptr<Effect>> audioEffects = {
smoothEffect,
#if SOSCI_FEATURES
screenSaturationEffect,
stereoEffect,
scaleEffect,
offsetEffect,
@ -309,6 +320,10 @@ public:
double getScreenSaturation() {
return parameters.screenSaturationEffect->getActualValue();
}
double getAfterglow() {
return parameters.afterglowEffect->getActualValue();
}
bool isFlippedVertical() {
return parameters.flipVertical->getBoolValue();
@ -379,6 +394,7 @@ private:
#if SOSCI_FEATURES
EffectComponent screenSaturation{*parameters.screenSaturationEffect};
EffectComponent afterglow{*parameters.afterglowEffect};
EffectComponent stereo{*parameters.stereoEffect};
EffectComponent xScale{*parameters.scaleEffect, 0};
EffectComponent yScale{*parameters.scaleEffect, 1};

Wyświetl plik

@ -4,7 +4,7 @@
addUsingNamespaceToJuceHeader="0" jucerFormatVersion="1" pluginCharacteristicsValue="pluginWantsMidiIn"
pluginManufacturer="jameshball" aaxIdentifier="sh.ball.oscirender"
cppLanguageStandard="20" projectLineFeed="&#10;" headerPath="./include"
version="2.4.5.2" companyName="James H Ball" companyWebsite="https://osci-render.com"
version="2.4.6.0" companyName="James H Ball" companyWebsite="https://osci-render.com"
companyEmail="james@ball.sh" defines="NOMINMAX=1&#10;INTERNET_FLAG_NO_AUTO_REDIRECT=0&#10;SOSCI_FEATURES=1"
pluginAUMainType="'aumf'">
<MAINGROUP id="j5Ge2T" name="osci-render">
@ -616,6 +616,10 @@
file="Source/UGen/ugen_JuceUtility.h"/>
</GROUP>
<GROUP id="{16A8DC64-BA02-898D-4DBA-AA3DDF6F9297}" name="visualiser">
<FILE id="DkDKBX" name="AfterglowFragmentShader.glsl" compile="0" resource="0"
file="Source/visualiser/AfterglowFragmentShader.glsl"/>
<FILE id="eM1kV3" name="AfterglowVertexShader.glsl" compile="0" resource="0"
file="Source/visualiser/AfterglowVertexShader.glsl"/>
<FILE id="kfMvdQ" name="BlurFragmentShader.glsl" compile="0" resource="0"
file="Source/visualiser/BlurFragmentShader.glsl" xcodeResource="0"/>
<FILE id="c59gvD" name="BlurVertexShader.glsl" compile="0" resource="0"

Wyświetl plik

@ -3,7 +3,7 @@
<JUCERPROJECT id="HH2E72" name="sosci" projectType="audioplug" useAppConfig="0"
addUsingNamespaceToJuceHeader="0" jucerFormatVersion="1" pluginManufacturer="jameshball"
aaxIdentifier="sh.ball.sosci" cppLanguageStandard="20" projectLineFeed="&#10;"
headerPath="./include" version="1.0.5.2" companyName="James H Ball"
headerPath="./include" version="1.1.0.0" companyName="James H Ball"
companyWebsite="https://osci-render.com" companyEmail="james@ball.sh"
defines="NOMINMAX=1&#10;INTERNET_FLAG_NO_AUTO_REDIRECT=0&#10;SOSCI_FEATURES=1"
pluginManufacturerCode="Jhba" pluginCode="Sosc" pluginAUMainType="'aufx'">
@ -167,6 +167,10 @@
<FILE id="NmptSY" name="Shape.h" compile="0" resource="0" file="Source/shape/Shape.h"/>
</GROUP>
<GROUP id="{04ACA01B-2ADE-8356-BF1E-32942E0F3CFA}" name="visualiser">
<FILE id="O444rE" name="AfterglowFragmentShader.glsl" compile="0" resource="0"
file="Source/visualiser/AfterglowFragmentShader.glsl"/>
<FILE id="kG6Zku" name="AfterglowVertexShader.glsl" compile="0" resource="0"
file="Source/visualiser/AfterglowVertexShader.glsl"/>
<FILE id="Y4j91J" name="BlurFragmentShader.glsl" compile="0" resource="0"
file="Source/visualiser/BlurFragmentShader.glsl"/>
<FILE id="Fimn0E" name="BlurVertexShader.glsl" compile="0" resource="0"