diff --git a/Source/visualiser/LineFragmentShader.glsl b/Source/visualiser/LineFragmentShader.glsl index 361524b..0c68ab0 100644 --- a/Source/visualiser/LineFragmentShader.glsl +++ b/Source/visualiser/LineFragmentShader.glsl @@ -9,7 +9,6 @@ uniform float uSize; uniform float uIntensity; uniform vec2 uOffset; uniform vec2 uScale; -uniform float uScreenOverlay; uniform float uFishEye; uniform sampler2D uScreen; varying float vSize; diff --git a/Source/visualiser/LineVertexShader.glsl b/Source/visualiser/LineVertexShader.glsl index 80d98c4..4b3cfa2 100644 --- a/Source/visualiser/LineVertexShader.glsl +++ b/Source/visualiser/LineVertexShader.glsl @@ -7,6 +7,7 @@ uniform float uSize; uniform float uNEdges; uniform float uFadeAmount; uniform float uIntensity; +uniform float uShutterLength; uniform float uGain; attribute vec3 aStart, aEnd; attribute float aIdx; @@ -56,17 +57,20 @@ void main () { uvl.w = aStartBrightness; } // `side` corresponds to shift to the "right" or "left" - float side = (mod(idx, 2.0)-0.5)*2.0; + float side = (mod(idx, 2.0) - 0.5) * 2.0; uvl.y = side * vSize; - uvl.w *= intensity * mix(1.0-uFadeAmount, 1.0, floor(aIdx / 4.0 + 0.5)/uNEdges); + float intensityScale = floor(aIdx / 4.0 + 0.5)/uNEdges; + float avgIntensityScale = floor((uNEdges / 2.0) / 4.0 + 0.5)/uNEdges; + float shutterLength = clamp(uShutterLength, 0.0, 1.0); + float adjustedIntensity = mix(intensityScale, avgIntensityScale, shutterLength); + float intensityFade = mix(1.0 - uFadeAmount, 1.0, adjustedIntensity); + + uvl.w *= intensity * intensityFade; vec4 pos = vec4((current+(tang*dir+norm*side)*vSize)*uInvert,0.0,1.0); gl_Position = pos; - vTexCoord = 0.5*pos.xy+0.5; - //float seed = floor(aIdx/4.0); - //seed = mod(sin(seed*seed), 7.0); - //if (mod(seed/2.0, 1.0)<0.5) gl_Position = vec4(10.0); + vTexCoord = 0.5 * pos.xy + 0.5; } )"; diff --git a/Source/visualiser/OutputFragmentShader.glsl b/Source/visualiser/OutputFragmentShader.glsl index 3837aff..133e859 100644 --- a/Source/visualiser/OutputFragmentShader.glsl +++ b/Source/visualiser/OutputFragmentShader.glsl @@ -65,7 +65,7 @@ void main() { // r components have grid; g components do not. vec4 screen = texture2D(uTexture3, vTexCoord); vec4 tightGlow = texture2D(uTexture1, linePos); - vec4 scatter = texture2D(uTexture2, linePos) + (1.0 - uRealScreen) * max(uAmbient - 0.35, 0.0); + vec4 scatter = texture2D(uTexture2, linePos); if (uRealScreen > 0.5) { vec4 reflection = texture2D(uTexture4, vTexCoord); @@ -73,8 +73,14 @@ void main() { scatter += max4(screenGlow * reflection * max(1.0 - 0.5 * uAmbient, 0.0), vec4(0.0)); } - float light = line.r + uGlow * 1.5 * screen.g * screen.g * tightGlow.r; - light += uGlow * 0.3 * scatter.g * (2.0 + 1.0 * screen.g + 0.5 * screen.r); + // making the range of the glow slider more useful + float glow = 1.05 * pow(uGlow, 1.5); + float light = line.r + glow * 1.5 * screen.g * screen.g * tightGlow.r; + float scatterScalar = 0.3 * (2.0 + 1.0 * screen.g + 0.5 * screen.r); + light += glow * scatter.g * scatterScalar; + // add ambient light to graticule + light += (1.0 - uRealScreen) * max(uAmbient - 0.35, 0.0) * scatterScalar; + float tlight = 1.0-pow(2.0, -uExposure*light); float tlight2 = tlight * tlight * tlight; gl_FragColor.rgb = mix(uColour, vec3(1.0), 0.3+tlight2*tlight2*uOverexposure) * tlight; diff --git a/Source/visualiser/VisualiserComponent.cpp b/Source/visualiser/VisualiserComponent.cpp index a74f5b5..4a72141 100644 --- a/Source/visualiser/VisualiserComponent.cpp +++ b/Source/visualiser/VisualiserComponent.cpp @@ -1091,8 +1091,11 @@ void VisualiserComponent::drawLine(const std::vector& xPoints, const std: setOffsetAndScale(lineShader.get()); #if SOSCI_FEATURES - lineShader->setUniform("uScreenOverlay", (GLfloat) screenOverlay); lineShader->setUniform("uFishEye", screenOverlay == ScreenOverlay::VectorDisplay ? VECTOR_DISPLAY_FISH_EYE : 0.0f); + lineShader->setUniform("uShutterLength", (GLfloat) settings.getShutterLength()); +#else + lineShader->setUniform("uFishEye", 0.0f); + lineShader->setUniform("uShutterLength", 0.0f); #endif glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer); diff --git a/Source/visualiser/VisualiserComponent.h b/Source/visualiser/VisualiserComponent.h index f7c234d..ef76054 100644 --- a/Source/visualiser/VisualiserComponent.h +++ b/Source/visualiser/VisualiserComponent.h @@ -240,7 +240,7 @@ private: juce::OpenGLShaderProgram* currentShader; float fadeAmount; - ScreenOverlay screenOverlay = ScreenOverlay::MAX; + ScreenOverlay screenOverlay = ScreenOverlay::INVALID; const double RESAMPLE_RATIO = 6.0; double sampleRate = -1; diff --git a/Source/visualiser/VisualiserSettings.h b/Source/visualiser/VisualiserSettings.h index 80ebd28..b016297 100644 --- a/Source/visualiser/VisualiserSettings.h +++ b/Source/visualiser/VisualiserSettings.h @@ -11,6 +11,7 @@ #include "../audio/StereoEffect.h" enum class ScreenOverlay : int { + INVALID = -1, Empty = 1, Graticule = 2, Smudged = 3, @@ -177,6 +178,14 @@ public: VERSION_HINT, 0.0, -1.0, 1.0 ), }); + std::shared_ptr shutterLengthEffect = std::make_shared( + new EffectParameter( + "Shutter Length", + "Controls the percentage of time the camera shutter is open over a frame. This can be beneficial when the drawing frequency and frame rate are in sync.", + "shutterLength", + VERSION_HINT, 0.0, 0.0, 1.0 + ) + ); #endif std::shared_ptr persistenceEffect = std::make_shared( @@ -285,6 +294,7 @@ public: screenSaturationEffect, screenHueEffect, overexposureEffect, + shutterLengthEffect, #endif }; std::vector> audioEffects = { @@ -395,6 +405,10 @@ public: bool isGoniometer() { return parameters.goniometer->getBoolValue(); } + + double getShutterLength() { + return parameters.shutterLengthEffect->getActualValue(); + } #endif double getFocus() { @@ -465,6 +479,7 @@ private: #if SOSCI_FEATURES std::make_shared(*parameters.afterglowEffect), std::make_shared(*parameters.overexposureEffect), + std::make_shared(*parameters.shutterLengthEffect), #else std::make_shared(*parameters.ambientEffect), #endif