diff --git a/orx-fx/src/main/kotlin/distort/DisplaceBlend.kt b/orx-fx/src/main/kotlin/distort/DisplaceBlend.kt new file mode 100644 index 00000000..21d68187 --- /dev/null +++ b/orx-fx/src/main/kotlin/distort/DisplaceBlend.kt @@ -0,0 +1,58 @@ +package org.openrndr.extra.fx.distort + +import org.openrndr.draw.* +import org.openrndr.extra.fx.filterFragmentCode +import org.openrndr.extra.parameters.BooleanParameter +import org.openrndr.extra.parameters.Description +import org.openrndr.extra.parameters.DoubleParameter +import org.openrndr.math.Vector3 + +@Description("Perturb") +class DisplaceBlend : Filter(Shader.createFromCode(filterVertexCode, filterFragmentCode("distort/displace-blend.frag"))) { + var seed: Vector3 by parameters + + @DoubleParameter("offset", -1.0, 1.0) + var offset: Double by parameters + + @DoubleParameter("gain", 0.0, 4.0) + var gain: Double by parameters + + @DoubleParameter("feather", 1.0, 100.0) + var feather: Double by parameters + + @DoubleParameter("rotation", -180.0, 180.0) + var rotation: Double by parameters + + @DoubleParameter("source opacity", 0.0, 1.0) + var sourceOpacity: Double by parameters + + @DoubleParameter("target opacity", 0.0, 1.0) + var targetOpacity: Double by parameters + + init { + gain = 0.1 + offset = 0.5 + rotation = 0.0 + feather = 1.0 + sourceOpacity = 1.0 + targetOpacity = 1.0 + } + + var bicubicFiltering = true + private var intermediate: ColorBuffer? = null + override fun apply(source: Array, target: Array) { + if (source.size >= 2) { + if (target[0] === source[0] || target[0] === source[1]) { + if (intermediate == null) { + intermediate = colorBuffer(target[0].width, target[0].height, type = target[0].type, format = target[0].format) + } + } + if (bicubicFiltering && source.isNotEmpty()) { + source[0].generateMipmaps() + source[0].filter(MinifyingFilter.LINEAR_MIPMAP_LINEAR, MagnifyingFilter.LINEAR) + } + super.apply(source, arrayOf(intermediate ?: target[0])) + intermediate?.copyTo(target[0]) + } + } +} \ No newline at end of file diff --git a/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/displace-blend.frag b/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/displace-blend.frag new file mode 100644 index 00000000..800fb5ab --- /dev/null +++ b/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/distort/displace-blend.frag @@ -0,0 +1,44 @@ +#version 330 core + +in vec2 v_texCoord0; +uniform sampler2D tex0;// input +uniform sampler2D tex1;// input +uniform float offset; +uniform float gain; +uniform vec2 targetSize; +uniform float rotation; +uniform float feather; +uniform float sourceOpacity; +uniform float targetOpacity; +out vec4 o_color; +void main() { + + + float phi = radians(rotation); + float cp = cos(phi); + float sp = sin(phi); + mat2 rm = mat2(vec2(cp,sp), vec2(-sp,cp)); + + vec4 oa = texture(tex0, v_texCoord0); + vec4 b = texture(tex1, v_texCoord0); + + float ar = targetSize.y / targetSize.x; + + vec4 nb = b.a > 0? b/b.a : vec4(0.0); + + vec2 offset = (nb.rg - vec2(offset))*vec2(gain) * nb.a; + offset = rm * offset * vec2(1.0, ar); + + + vec2 step = fwidth(v_texCoord0) * feather; + + vec2 displaced = v_texCoord0 + offset; + + float fx = smoothstep(0.0, step.x, displaced.x) * smoothstep(1.0, 1.0-step.x, displaced.x); + float fy = smoothstep(0.0, step.y, displaced.y) * smoothstep(1.0, 1.0-step.y, displaced.y); + + vec4 a = texture(tex0, displaced) * mix(1.0, fx * fy, b.a); + + o_color = (a + (1.0-a.a) * oa * sourceOpacity) * b.a * targetOpacity + (1.0-b.a*targetOpacity) * oa * sourceOpacity; + +}