From 538590c2f04bf67c57defe9267dd6a9709ee7d7d Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Wed, 6 May 2020 16:55:37 +0200 Subject: [PATCH] Add VideoGlitch and TapeNoise filters --- orx-fx/build.gradle | 1 + orx-fx/src/main/kotlin/blur/LaserBlur.kt | 2 - orx-fx/src/main/kotlin/distort/TapeNoise.kt | 29 ++++++++ orx-fx/src/main/kotlin/distort/VideoGlitch.kt | 56 +++++++++++++++ .../extra/fx/gl3/distort/tape-noise.frag | 53 ++++++++++++++ .../extra/fx/gl3/distort/video-glitch.frag | 69 +++++++++++++++++++ 6 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 orx-fx/src/main/kotlin/distort/TapeNoise.kt create mode 100644 orx-fx/src/main/kotlin/distort/VideoGlitch.kt create mode 100644 orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/tape-noise.frag create mode 100644 orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/video-glitch.frag diff --git a/orx-fx/build.gradle b/orx-fx/build.gradle index 103d1690..45f3e8e3 100644 --- a/orx-fx/build.gradle +++ b/orx-fx/build.gradle @@ -11,6 +11,7 @@ sourceSets { dependencies { api project(":orx-parameters") implementation project(":orx-noise") + demoImplementation("org.openrndr:openrndr-ffmpeg:$openrndrVersion") demoImplementation("org.openrndr:openrndr-core:$openrndrVersion") demoImplementation("org.openrndr:openrndr-extensions:$openrndrVersion") demoImplementation(project(":orx-gui")) diff --git a/orx-fx/src/main/kotlin/blur/LaserBlur.kt b/orx-fx/src/main/kotlin/blur/LaserBlur.kt index b22a049d..648c4c52 100644 --- a/orx-fx/src/main/kotlin/blur/LaserBlur.kt +++ b/orx-fx/src/main/kotlin/blur/LaserBlur.kt @@ -5,10 +5,8 @@ import org.openrndr.draw.ColorType import org.openrndr.draw.Filter import org.openrndr.draw.filterShaderFromUrl import org.openrndr.extra.fx.filterFragmentUrl -import org.openrndr.extra.noise.simplex import org.openrndr.extra.parameters.* import org.openrndr.math.Vector2 -import java.lang.Math.pow private class LaserBlurPass : Filter(filterShaderFromUrl(filterFragmentUrl("blur/laser-blur.frag"))) { var radius: Double by parameters diff --git a/orx-fx/src/main/kotlin/distort/TapeNoise.kt b/orx-fx/src/main/kotlin/distort/TapeNoise.kt new file mode 100644 index 00000000..52af6cfd --- /dev/null +++ b/orx-fx/src/main/kotlin/distort/TapeNoise.kt @@ -0,0 +1,29 @@ +package org.openrndr.extra.fx.distort + + +import org.openrndr.draw.Filter +import org.openrndr.draw.filterShaderFromUrl +import org.openrndr.extra.fx.filterFragmentUrl +import org.openrndr.extra.parameters.Description +import org.openrndr.extra.parameters.DoubleParameter + + +@Description("Tape noise") +class TapeNoise : Filter(filterShaderFromUrl(filterFragmentUrl("distort/tape-noise.frag"))) { + var time: Double by parameters + + @DoubleParameter("gain", 0.0, 1.0) + var gain: Double by parameters + + @DoubleParameter("noise low", 0.0, 1.0) + var noiseLow: Double by parameters + + @DoubleParameter("noise high", 0.0, 1.0) + var noiseHigh: Double by parameters + + init { + gain = 0.5 + noiseLow = 0.5 + noiseHigh = 0.8 + } +} \ No newline at end of file diff --git a/orx-fx/src/main/kotlin/distort/VideoGlitch.kt b/orx-fx/src/main/kotlin/distort/VideoGlitch.kt new file mode 100644 index 00000000..9f869411 --- /dev/null +++ b/orx-fx/src/main/kotlin/distort/VideoGlitch.kt @@ -0,0 +1,56 @@ +package org.openrndr.extra.fx.distort + +import org.openrndr.draw.Filter +import org.openrndr.draw.filterShaderFromUrl +import org.openrndr.extra.fx.filterFragmentUrl +import org.openrndr.extra.parameters.BooleanParameter +import org.openrndr.extra.parameters.Description +import org.openrndr.extra.parameters.DoubleParameter + +@Description("Video glitch") +class VideoGlitch : Filter(filterShaderFromUrl(filterFragmentUrl("distort/video-glitch.frag"))) { + var time: Double by parameters + + @DoubleParameter("amplitude", 0.0, 10.0) + var amplitude: Double by parameters + + @DoubleParameter("border height", 0.0, 0.5) + var borderHeight: Double by parameters + + @DoubleParameter("vertical frequency", 0.0, 10.0) + var vfreq: Double by parameters + + @DoubleParameter("horizontal frequency", 0.0, 80.0) + var hfreq: Double by parameters + + @DoubleParameter("p frequency", 0.0, 10.0) + var pfreq: Double by parameters + + @DoubleParameter("p offset", -1.0, 1.0) + var poffset: Double by parameters + + @DoubleParameter("scroll offset 0", 0.0, 1.0) + var scrollOffset0: Double by parameters + + @DoubleParameter("scroll offset 1", 0.0, 1.0) + var scrollOffset1: Double by parameters + + @BooleanParameter("linear input") + var linearInput: Boolean by parameters + + @BooleanParameter("linear output") + var linearOutput: Boolean by parameters + + init { + amplitude = 1.0 + vfreq = 4.0 + pfreq = 10.0 + hfreq = 80.0 + poffset = 0.0 + scrollOffset0 = 0.0 + scrollOffset1 = 0.0 + borderHeight = 0.05 + linearInput = false + linearOutput = false + } +} \ No newline at end of file diff --git a/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/tape-noise.frag b/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/tape-noise.frag new file mode 100644 index 00000000..9045a859 --- /dev/null +++ b/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/tape-noise.frag @@ -0,0 +1,53 @@ +#version 330 core +out vec4 o_output; +uniform sampler2D tex0; +in vec2 v_texCoord0; +uniform float time; + +uniform float gain; +uniform float noiseLow; +uniform float noiseHigh; + +#define HASHSCALE 443.8975 +vec2 hash22(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * HASHSCALE); + p3 += dot(p3, p3.yzx+19.19); + return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y)); +} + +vec3 saturate(vec3 x) { + return clamp(x, vec3(0.0), vec3(1.0)); +} + +vec3 aberrationColor(float f) { + f = f * 3.0 - 1.5; + return saturate(vec3(-f, 1.0 - abs(f), f)); +} + +void main() { + float dk = 1.0/600.0; + for (int k = 0; k < 10; ++k ) { + vec2 duv = v_texCoord0; + duv.y += smoothstep(pow(cos(time+k*dk+v_texCoord0.y*1.0),10.0)*0.1+0.1, 0.0, v_texCoord0.x)*0.1 * cos(time+k*dk); + duv.y += smoothstep(pow(1.0-cos(time+k*dk+v_texCoord0.y*1.0),10.0)*0.1+0.1, 0.9, v_texCoord0.x)*0.1 * cos(time+k*dk); + duv.y += sin(v_texCoord0.x*3.1415926535)*0.0; + float bc = floor(hash22(vec2(time+k*dk, (time+k*dk)*0.1)).x*20.0); + + float gb3 = floor(duv.y*bc)/bc; + + vec2 v = hash22(duv.xy*0.003+time+k*dk); + vec2 v2 = hash22(duv.xy*0.03+time+k*dk); + vec2 v2b = hash22(duv.yx*0.03+time+k*dk); + float stretch = (cos(time+k*dk)*0.001+0.002)*0.3+0.001; + vec2 h = hash22(duv.yy*stretch+time+k*dk); + float gap = smoothstep(-1.0, -0.99, cos(gb3*(10.0+duv.y*10.0 + (time+k*dk)*10.0) +duv.x*10.0)) * (cos(gb3)*0.5+0.5); + + float r = smoothstep(noiseLow, noiseHigh, h.x*gap*v2.x)*1.0; + float g = smoothstep(noiseLow, noiseHigh, h.x*gap*v2.y)*1.0; + float b = smoothstep(noiseLow, noiseHigh, h.x*gap*v2b.x)*1.0; + float a = smoothstep(noiseLow, noiseHigh, h.x*gap*v2b.y)*1.0; + o_output += vec4(r,g,b,a)*gain; + } + o_output *= o_output.a; + o_output += texture(tex0, v_texCoord0); +} \ No newline at end of file diff --git a/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/video-glitch.frag b/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/video-glitch.frag new file mode 100644 index 00000000..1feedd46 --- /dev/null +++ b/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/video-glitch.frag @@ -0,0 +1,69 @@ +#version 330 core +out vec4 o_output; +uniform sampler2D tex0; +in vec2 v_texCoord0; +uniform float time; +uniform float amplitude; +uniform float vfreq; +uniform float pfreq; +uniform float hfreq; +uniform float poffset; +uniform float scrollOffset0; +uniform float scrollOffset1; + +uniform float borderHeight; + +uniform bool linearInput; +uniform bool linearOutput; + +#define HASHSCALE 443.8975 +vec2 hash22(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * HASHSCALE); + p3 += dot(p3, p3.yzx+19.19); + return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y)); +} + +vec3 saturate(vec3 x) { + return clamp(x, vec3(0.0), vec3(1.0)); +} + +vec4 getVideo(vec2 uv, float amplitude, float seconds) { + float iTime = seconds; + vec2 look = mod(uv, vec2(1.0)); + float window = 1.0/(1.0 + 20.0*(look.y-mod(iTime*vfreq, 1.0))*(look.y-mod(iTime*vfreq, 1.))); + look.x = look.x + sin(look.y*pfreq + poffset * 3.1415)/50 *(1.+cos(iTime*hfreq))*window*amplitude; + look.y = mod(look.y, 1.); + + vec4 video = texture(tex0, look); + return video; +} + +vec4 aberrationColor(float f) { + f = f * 3.0 - 1.5; + return vec4(saturate(vec3(-f, 1.0 - abs(f), f)), 1.0); +} + +void main() { + vec4 c = vec4(0.0); + float aa = amplitude + smoothstep(borderHeight, 0.0, v_texCoord0.y)*4.0 + smoothstep(1.0-borderHeight, 1.0, v_texCoord0.y)*4.0; + float ds = scrollOffset1 - scrollOffset0; + if (aa > 0.0 || ds > 0.0) { + for (int i = 1; i < 16; ++i) { + vec4 lc = getVideo(v_texCoord0 + vec2(0.0, scrollOffset0+ds*i), aa, time-i/(16*60.0)); + if (!linearInput) { + lc.rgb = pow(lc.rgb, vec3(2.2)); + } + c += lc * (3.0/16.0) * aberrationColor(i/16.0); + } + o_output = c; + } else { + vec4 lc = texture(tex0, mod(v_texCoord0 + vec2(0.0, scrollOffset1), vec2(1.0))); + if (!linearInput) { + lc.rgb = pow(lc.rgb, vec3(2.2)); + } + o_output = lc; + } + if (!linearOutput) { + o_output.rgb = pow(o_output.rgb, vec3(1/2.2)); + } +}