From 6274e29349c226cdfad7e767c48feae3e1b4b314 Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Mon, 30 Aug 2021 11:45:47 +0200 Subject: [PATCH] [orx-fx] Add PolarToRectangular, RectangularToPolar and LineBlur --- orx-fx/build.gradle.kts | 29 +++++---- orx-fx/src/commonMain/kotlin/blur/BoxBlur.kt | 2 + orx-fx/src/commonMain/kotlin/blur/LineBlur.kt | 65 +++++++++++++++++++ .../kotlin/distort/PolarToRectangular.kt | 23 +++++++ .../kotlin/distort/RectangularToPolar.kt | 23 +++++++ orx-fx/src/shaders/glsl/blur/box-blur.frag | 19 +++++- .../glsl/distort/polar-to-rectangular.frag | 33 ++++++++++ .../glsl/distort/rectangular-to-polar.frag | 40 ++++++++++++ 8 files changed, 219 insertions(+), 15 deletions(-) create mode 100644 orx-fx/src/commonMain/kotlin/blur/LineBlur.kt create mode 100644 orx-fx/src/commonMain/kotlin/distort/PolarToRectangular.kt create mode 100644 orx-fx/src/commonMain/kotlin/distort/RectangularToPolar.kt create mode 100644 orx-fx/src/shaders/glsl/distort/polar-to-rectangular.frag create mode 100644 orx-fx/src/shaders/glsl/distort/rectangular-to-polar.frag diff --git a/orx-fx/build.gradle.kts b/orx-fx/build.gradle.kts index 5b01c490..1288726f 100644 --- a/orx-fx/build.gradle.kts +++ b/orx-fx/build.gradle.kts @@ -18,6 +18,15 @@ val openrndrVersion: String by rootProject.extra val openrndrOS: String by rootProject.extra val spekVersion: String by rootProject.extra +val embedShaders = tasks.register("embedShaders") { + inputDir.set(file("$projectDir/src/shaders/glsl")) + outputDir.set(file("$buildDir/generated/shaderKotlin")) + defaultPackage.set("org.openrndr.extra.fx") + defaultVisibility.set("internal") + namePrefix.set("fx_") +}.get() + + kotlin { jvm { compilations { @@ -50,7 +59,8 @@ kotlin { sourceSets { val shaderKotlin by creating { - this.kotlin.srcDir("$projectDir/build/generated/shaderKotlin") + //this.kotlin.srcDir("$projectDir/build/generated/shaderKotlin") + this.kotlin.srcDir(embedShaders.outputDir) } @Suppress("UNUSED_VARIABLE") val commonMain by getting { @@ -104,16 +114,9 @@ kotlin { } } -val embedShaders = tasks.register("embedShaders") { - inputDir.set(file("$projectDir/src/shaders/glsl")) - outputDir.set(file("$buildDir/generated/shaderKotlin")) - defaultPackage.set("org.openrndr.extra.fx") - defaultVisibility.set("internal") - namePrefix.set("fx_") -}.get() -tasks.getByName("compileKotlinJvm").dependsOn(embedShaders) -tasks.getByName("compileKotlinJs").dependsOn(embedShaders) -tasks.getByName("compileKotlinMetadata").dependsOn(embedShaders) -tasks.getByName("jvmSourcesJar").dependsOn(embedShaders) -tasks.getByName("sourcesJar").dependsOn(embedShaders) +//tasks.getByName("compileKotlinJvm").dependsOn(embedShaders) +//tasks.getByName("compileKotlinJs").dependsOn(embedShaders) +//tasks.getByName("compileKotlinMetadata").dependsOn(embedShaders) +//tasks.getByName("jvmSourcesJar").dependsOn(embedShaders) +//tasks.getByName("sourcesJar").dependsOn(embedShaders) diff --git a/orx-fx/src/commonMain/kotlin/blur/BoxBlur.kt b/orx-fx/src/commonMain/kotlin/blur/BoxBlur.kt index 0540258a..2d7a233f 100644 --- a/orx-fx/src/commonMain/kotlin/blur/BoxBlur.kt +++ b/orx-fx/src/commonMain/kotlin/blur/BoxBlur.kt @@ -49,6 +49,8 @@ class BoxBlur : Filter(mppFilterShader(fx_box_blur,"box-blur")) { colorBuffer(target[0].width, target[0].height, target[0].contentScale, target[0].format, target[0].type) } + parameters["wrapX"] = false + parameters["wrapY"] = false intermediate.let { parameters["blurDirection"] = Vector2(1.0, 0.0) super.apply(source, arrayOf(it)) diff --git a/orx-fx/src/commonMain/kotlin/blur/LineBlur.kt b/orx-fx/src/commonMain/kotlin/blur/LineBlur.kt new file mode 100644 index 00000000..c2672028 --- /dev/null +++ b/orx-fx/src/commonMain/kotlin/blur/LineBlur.kt @@ -0,0 +1,65 @@ +package org.openrndr.extra.fx.blur + +import org.openrndr.draw.* +import org.openrndr.extra.fx.fx_box_blur +import org.openrndr.extra.fx.mppFilterShader +import org.openrndr.extra.parameters.BooleanParameter +import org.openrndr.extra.parameters.Description +import org.openrndr.extra.parameters.DoubleParameter +import org.openrndr.extra.parameters.IntParameter + +import org.openrndr.math.Vector2 +import org.openrndr.math.asRadians +import kotlin.math.cos +import kotlin.math.sin + +/** + * BoxBlur implemented as a separable filter + */ +@Description("Box-blur") +class LineBlur : Filter(mppFilterShader(fx_box_blur, "line-blur")) { + + /** + * The sample window, default is 5 + */ + @IntParameter("window size", 1, 25) + var window: Int by parameters + + /** + * Spread multiplier, default is 1.0 + */ + @DoubleParameter("kernel spread", 1.0, 4.0) + var spread: Double by parameters + + /** + * Post-blur gain, default is 1.0 + */ + @DoubleParameter("gain", 0.0, 4.0) + var gain: Double by parameters + + + @DoubleParameter("blur angle", -180.0, 180.0) + var blurAngle: Double by parameters + + @BooleanParameter("wrap x", order = 9) + var wrapX: Boolean by parameters + + @BooleanParameter("wrap y", order = 10) + var wrapY: Boolean by parameters + + + + init { + window = 5 + spread = 1.0 + gain = 1.0 + blurAngle = 0.0 + wrapX = false + wrapY = false + } + + override fun apply(source: Array, target: Array) { + parameters["blurDirection"] = Vector2(cos(blurAngle.asRadians), sin(blurAngle.asRadians)) + super.apply(source, target) + } +} \ No newline at end of file diff --git a/orx-fx/src/commonMain/kotlin/distort/PolarToRectangular.kt b/orx-fx/src/commonMain/kotlin/distort/PolarToRectangular.kt new file mode 100644 index 00000000..3fece00b --- /dev/null +++ b/orx-fx/src/commonMain/kotlin/distort/PolarToRectangular.kt @@ -0,0 +1,23 @@ +package org.openrndr.extra.fx.distort + +import org.openrndr.draw.ColorBuffer +import org.openrndr.draw.Filter +import org.openrndr.draw.MagnifyingFilter +import org.openrndr.draw.MinifyingFilter +import org.openrndr.extra.fx.fx_polar_to_rectangular +import org.openrndr.extra.fx.mppFilterShader +import org.openrndr.extra.parameters.Description +import org.openrndr.extra.parameters.Vector2Parameter +import org.openrndr.math.Vector2 + +@Description("Polar to rectangular") +class PolarToRectangular : Filter(mppFilterShader(fx_polar_to_rectangular, "polar-to-rectangular")) { + var bicubicFiltering = true + override fun apply(source: Array, target: Array) { + if (bicubicFiltering && source.isNotEmpty()) { + source[0].generateMipmaps() + source[0].filter(MinifyingFilter.LINEAR_MIPMAP_LINEAR, MagnifyingFilter.LINEAR) + } + super.apply(source, target) + } +} \ No newline at end of file diff --git a/orx-fx/src/commonMain/kotlin/distort/RectangularToPolar.kt b/orx-fx/src/commonMain/kotlin/distort/RectangularToPolar.kt new file mode 100644 index 00000000..9082d513 --- /dev/null +++ b/orx-fx/src/commonMain/kotlin/distort/RectangularToPolar.kt @@ -0,0 +1,23 @@ +package org.openrndr.extra.fx.distort + +import org.openrndr.draw.ColorBuffer +import org.openrndr.draw.Filter +import org.openrndr.draw.MagnifyingFilter +import org.openrndr.draw.MinifyingFilter +import org.openrndr.extra.fx.fx_rectangular_to_polar +import org.openrndr.extra.fx.mppFilterShader +import org.openrndr.extra.parameters.Description +import org.openrndr.extra.parameters.Vector2Parameter +import org.openrndr.math.Vector2 + +@Description("Rectangular to polar") +class RectangularToPolar : Filter(mppFilterShader(fx_rectangular_to_polar, "rectangular-to-polar")) { + var bicubicFiltering = true + override fun apply(source: Array, target: Array) { + if (bicubicFiltering && source.isNotEmpty()) { + source[0].generateMipmaps() + source[0].filter(MinifyingFilter.LINEAR_MIPMAP_LINEAR, MagnifyingFilter.LINEAR) + } + super.apply(source, target) + } +} \ No newline at end of file diff --git a/orx-fx/src/shaders/glsl/blur/box-blur.frag b/orx-fx/src/shaders/glsl/blur/box-blur.frag index a47eca7e..83c48c98 100644 --- a/orx-fx/src/shaders/glsl/blur/box-blur.frag +++ b/orx-fx/src/shaders/glsl/blur/box-blur.frag @@ -14,10 +14,25 @@ uniform float gain; uniform vec4 subtract; uniform float spread; +uniform bool wrapX; +uniform bool wrapY; + + #ifndef OR_GL_FRAGCOLOR out vec4 o_color; #endif +vec2 wrap(vec2 uv) { + vec2 res = uv; + if (wrapX) { + res.x = mod(res.x, 1.0); + } + if (wrapY) { + res.y = mod(res.y, 1.0); + } + return res; + +} void main() { vec2 s = textureSize0; s = vec2(1.0 / s.x, 1.0 / s.y); @@ -37,9 +52,9 @@ void main() { for (int x = WS; x<= WE; ++x) { float lw = 1.0; #ifndef OR_GL_TEXTURE2D - sum += texture(tex0, v_texCoord0 + float(x) * blurDirection * s * spread); + sum += texture(tex0, wrap(v_texCoord0 + float(x) * blurDirection * s * spread)); #else - sum += texture2D(tex0, v_texCoord0 + float(x) * blurDirection * s * spread); + sum += texture2D(tex0, wrap(v_texCoord0 + float(x) * blurDirection * s * spread)); #endif weight += lw; diff --git a/orx-fx/src/shaders/glsl/distort/polar-to-rectangular.frag b/orx-fx/src/shaders/glsl/distort/polar-to-rectangular.frag new file mode 100644 index 00000000..2fa88350 --- /dev/null +++ b/orx-fx/src/shaders/glsl/distort/polar-to-rectangular.frag @@ -0,0 +1,33 @@ +#ifdef OR_IN_OUT +in vec2 v_texCoord0; +#else +varying vec2 v_texCoord0; +#endif + +uniform vec2 textureSize0; +uniform sampler2D tex0; + +#ifndef OR_GL_FRAGCOLOR +out vec4 o_color; +#endif + +#define PI 3.141592653589793 + +void main() { + vec2 uv = v_texCoord0 - vec2(0.5); + float arg = atan(uv.y, uv.x); + float radius = length(uv); + vec2 sourceUV = vec2(arg / (2*PI) + 0.5, radius/sqrt(0.5)); + + #ifndef OR_GL_TEXTURE2D + vec4 result = texture(tex0, sourceUV); + #else + vec4 result = texture2D(tex0, sourceUV); + #endif + + #ifdef OR_GL_FRAGCOLOR + gl_FragColor = result; + #else + o_color = result; + #endif +} \ No newline at end of file diff --git a/orx-fx/src/shaders/glsl/distort/rectangular-to-polar.frag b/orx-fx/src/shaders/glsl/distort/rectangular-to-polar.frag new file mode 100644 index 00000000..9c6bfef5 --- /dev/null +++ b/orx-fx/src/shaders/glsl/distort/rectangular-to-polar.frag @@ -0,0 +1,40 @@ +#ifdef OR_IN_OUT +in vec2 v_texCoord0; +#else +varying vec2 v_texCoord0; +#endif + +uniform vec2 textureSize0; +uniform sampler2D tex0; +uniform vec2 origin; + +#ifndef OR_GL_FRAGCOLOR +out vec4 o_color; +#endif + +#define PI 3.141592653589793 + +uniform int angleLevels; +uniform int radiusLevels; + +void main() { + vec2 uv = v_texCoord0 - origin; + float arg = (uv.x-0.5) * 2 * PI; + float radius = (uv.y) * sqrt(0.5); + + + vec2 sourceUV = radius * vec2(cos(arg), sin(arg)) + vec2(0.5); + + #ifndef OR_GL_TEXTURE2D + vec4 result = texture(tex0, sourceUV); + #else + vec4 result = texture2D(tex0, sourceUV); + #endif + + #ifdef OR_GL_FRAGCOLOR + gl_FragColor = result; + #else + o_color = result; + #endif +} +