From aebec990e0739c6209ab78f5a50aa1a6b47c8156 Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Tue, 19 Aug 2025 13:54:55 +0200 Subject: [PATCH] [orx-fx] Add wrap mode support to ApproximateGaussianBlur and demo --- .../kotlin/blur/ApproximateGaussianBlur.kt | 17 ++++++++++ .../kotlin/DemoApproximateGaussianBlur01.kt | 31 +++++++++++++++++++ .../glsl/blur/approximate-gaussian-blur.frag | 10 ++++++ 3 files changed, 58 insertions(+) create mode 100644 orx-fx/src/jvmDemo/kotlin/DemoApproximateGaussianBlur01.kt diff --git a/orx-fx/src/commonMain/kotlin/blur/ApproximateGaussianBlur.kt b/orx-fx/src/commonMain/kotlin/blur/ApproximateGaussianBlur.kt index 8f67b203..b2fe5fae 100644 --- a/orx-fx/src/commonMain/kotlin/blur/ApproximateGaussianBlur.kt +++ b/orx-fx/src/commonMain/kotlin/blur/ApproximateGaussianBlur.kt @@ -6,6 +6,7 @@ import org.openrndr.draw.* import org.openrndr.extra.fx.ColorBufferDescription import org.openrndr.extra.fx.fx_approximate_gaussian_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 @@ -18,6 +19,14 @@ import org.openrndr.shape.Rectangle */ @Description("Approximate Gaussian blur") class ApproximateGaussianBlur : Filter1to1(mppFilterShader(fx_approximate_gaussian_blur, "approximate gaussian blur")) { + + @BooleanParameter("wrap u") + var wrapU = false + + @BooleanParameter("wrap v") + var wrapV = false + + /** * blur sample window, default value is 5 */ @@ -58,6 +67,8 @@ class ApproximateGaussianBlur : Filter1to1(mppFilterShader(fx_approximate_gaussi } intermediate.let { + parameters["wrapU"] = if (wrapU) 1 else 0 + parameters["wrapV"] = if (wrapV) 1 else 0 parameters["blurDirection"] = Vector2(1.0, 0.0) super.apply(source, arrayOf(it), clip) @@ -65,4 +76,10 @@ class ApproximateGaussianBlur : Filter1to1(mppFilterShader(fx_approximate_gaussi super.apply(arrayOf(it), target, clip) } } + + override fun close() { + intermediateCache.values.forEach { it.close() } + intermediateCache.clear() + super.close() + } } \ No newline at end of file diff --git a/orx-fx/src/jvmDemo/kotlin/DemoApproximateGaussianBlur01.kt b/orx-fx/src/jvmDemo/kotlin/DemoApproximateGaussianBlur01.kt new file mode 100644 index 00000000..bac12fef --- /dev/null +++ b/orx-fx/src/jvmDemo/kotlin/DemoApproximateGaussianBlur01.kt @@ -0,0 +1,31 @@ +import org.openrndr.application +import org.openrndr.draw.createEquivalent +import org.openrndr.draw.loadImage +import org.openrndr.extra.fx.blur.ApproximateGaussianBlur +import org.openrndr.extra.imageFit.imageFit + +fun main() = application { + configure { + width = 720 + height = 720 + } + program { + val image = loadImage("demo-data/images/image-001.png") + val blurred = image.createEquivalent() + val blur = ApproximateGaussianBlur() + + var enableWrap = false + + mouse.buttonDown.listen { + enableWrap = !enableWrap + } + extend { + blur.wrapU = enableWrap + blur.wrapV = enableWrap + blur.sigma = 15.0 + blur.window = 15 + blur.apply(image, blurred) + drawer.imageFit(blurred, drawer.bounds) + } + } +} \ No newline at end of file diff --git a/orx-fx/src/shaders/glsl/blur/approximate-gaussian-blur.frag b/orx-fx/src/shaders/glsl/blur/approximate-gaussian-blur.frag index 8bd52737..d4b7562f 100644 --- a/orx-fx/src/shaders/glsl/blur/approximate-gaussian-blur.frag +++ b/orx-fx/src/shaders/glsl/blur/approximate-gaussian-blur.frag @@ -6,6 +6,8 @@ uniform int window; uniform float sigma; uniform float spread; uniform float gain; +uniform int wrapU; +uniform int wrapV; uniform int sourceLevel; @@ -19,6 +21,14 @@ void main() { for (int x = -w; x <= w; ++x) { float lw = exp( float(-(x*x)) / (2.0 * sigma * sigma) ) ; vec2 tc = v_texCoord0 + float(x) * blurDirection * s;// * spread; + + if (wrapU != 0) { + tc.x = mod(tc.x, 1.0); + } + if (wrapV != 0) { + tc.y = mod(tc.y, 1.0); + } + sum += texture(tex0, tc) * lw; weight += lw; }