From aec57f7a440fc9513537048ca46b176b7ca18952 Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Thu, 4 Jul 2024 21:04:31 +0200 Subject: [PATCH] [orx-jumpflood] Add signedMagnitude mode to DirectionalField --- .../src/commonMain/kotlin/DirectionalField.kt | 5 ++ .../src/commonMain/kotlin/JumpFlood.kt | 2 + .../jvmDemo/kotlin/DemoDirectionField02.kt | 54 +++++++++++++++++++ .../src/shaders/glsl/pixel-direction.frag | 18 +++++-- 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 orx-jumpflood/src/jvmDemo/kotlin/DemoDirectionField02.kt diff --git a/orx-jumpflood/src/commonMain/kotlin/DirectionalField.kt b/orx-jumpflood/src/commonMain/kotlin/DirectionalField.kt index 2b0df079..4df49402 100644 --- a/orx-jumpflood/src/commonMain/kotlin/DirectionalField.kt +++ b/orx-jumpflood/src/commonMain/kotlin/DirectionalField.kt @@ -28,6 +28,10 @@ class DirectionalField : Filter1to1() { @BooleanParameter("unit direction") var unitDirection = false + @BooleanParameter("signed magnitude") + var signedMagnitude = false + + @BooleanParameter("flip v direction") var flipV = true @@ -87,6 +91,7 @@ class DirectionalField : Filter1to1() { decodeFilter.distanceScale = distanceScale decodeFilter.normalizedDistance = normalizedDistance decodeFilter.unitDirection = unitDirection + decodeFilter.signedMagnitude = signedMagnitude decodeFilter.flipV = flipV decodeFilter.apply(arrayOf(result, thresholded!!), arrayOf(result)) result.copyTo(target[0], diff --git a/orx-jumpflood/src/commonMain/kotlin/JumpFlood.kt b/orx-jumpflood/src/commonMain/kotlin/JumpFlood.kt index 323583cb..8a94bd1c 100644 --- a/orx-jumpflood/src/commonMain/kotlin/JumpFlood.kt +++ b/orx-jumpflood/src/commonMain/kotlin/JumpFlood.kt @@ -38,6 +38,7 @@ class PixelDirection(val decodeMode: DecodeMode = DecodeMode.DIRECTION) : var originalSize: Vector2 by parameters var normalizedDistance: Boolean by parameters var unitDirection: Boolean by parameters + var signedMagnitude: Boolean by parameters var flipV: Boolean by parameters var outputIds: Boolean by parameters @@ -49,6 +50,7 @@ class PixelDirection(val decodeMode: DecodeMode = DecodeMode.DIRECTION) : unitDirection = false flipV = true outputIds = false + signedMagnitude = false } } diff --git a/orx-jumpflood/src/jvmDemo/kotlin/DemoDirectionField02.kt b/orx-jumpflood/src/jvmDemo/kotlin/DemoDirectionField02.kt new file mode 100644 index 00000000..3963dfa3 --- /dev/null +++ b/orx-jumpflood/src/jvmDemo/kotlin/DemoDirectionField02.kt @@ -0,0 +1,54 @@ +import org.openrndr.MouseTracker +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.* +import org.openrndr.drawImage +import org.openrndr.extra.jumpfill.DirectionalField +import org.openrndr.extra.noise.scatter +import org.openrndr.extra.noise.simplex +import org.openrndr.math.IntVector2 +import org.openrndr.math.Vector2 +import org.openrndr.math.Vector3 +import org.openrndr.math.clamp +import org.openrndr.shape.Rectangle +import kotlin.math.abs + +/** + * Create directional distance field and demonstrate signed distance + */ +fun main() = application { + configure { + width = 1024 + height = 1024 + } + + program { + val input = drawImage(width, height, contentScale = 1.0) { + val points = drawer.bounds.scatter(100.0) + drawer.circles(points, 50.0) + } + + val filter = DirectionalField() + val ddf = input.createEquivalent(type = ColorType.FLOAT32) + + filter.signedMagnitude = true + filter.unitDirection = true + filter.apply(input, ddf) + + ddf.shadow.download() + extend { + val p = (mouse.position * ddf.contentScale).toInt().clamp(IntVector2.ZERO, IntVector2(width-1, height-1)) + val c = ddf.shadow[p.x, p.y] + val sdf3 = Vector3(c.r, c.g, c.b) + + drawer.drawStyle.colorMatrix = constant(ColorRGBa.WHITE.shade(0.5)) * tint(ColorRGBa.WHITE.shade(0.5)) + + drawer.image(ddf) + drawer.fill = null + drawer.stroke = ColorRGBa.WHITE + + drawer.circle(mouse.position, sdf3.z / ddf.contentScale) + drawer.lineSegment(mouse.position, mouse.position + sdf3.xy * sdf3.z) + } + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/shaders/glsl/pixel-direction.frag b/orx-jumpflood/src/shaders/glsl/pixel-direction.frag index f38b592b..1fc7fd09 100644 --- a/orx-jumpflood/src/shaders/glsl/pixel-direction.frag +++ b/orx-jumpflood/src/shaders/glsl/pixel-direction.frag @@ -1,4 +1,3 @@ - /* use #define OUTPUT_DISTANCE to output distance use #define OUTPUT_DIRECTION to output direction @@ -13,6 +12,7 @@ uniform bool normalizedDistance; uniform bool unitDirection; uniform bool flipV; uniform bool outputIds; +uniform bool signedMagnitude; in vec2 v_texCoord0; out vec4 o_color; @@ -23,7 +23,7 @@ void main() { vec2 pixelPosition = v_texCoord0; vec4 textureData = texture(tex0, v_texCoord0); - vec2 centroidPixelPosition = textureData.xy; + vec2 centroidPixelPosition = textureData.xy; vec2 pixelDistance = (centroidPixelPosition - pixelPosition) * sizeDF; @@ -32,8 +32,8 @@ void main() { pixelDistance *= vec2(1.0, -1.0); } + float length = length(pixelDistance); if (unitDirection) { - float length = length(pixelDistance); if (length >= 1E-6) { pixelDistance /= length; } @@ -51,9 +51,17 @@ void main() { } #else if (!normalizedDistance) { - o_color = vec4( vec2(length(pixelDistance * distanceScale)), outputData, 1.0); + o_color = vec4(vec2(length(pixelDistance * distanceScale)), outputData, 1.0); } else if (!unitDirection) { - o_color = vec4( vec2(length(pixelDistance / originalSize)), outputData, 1.0); + o_color = vec4(vec2(length(pixelDistance / originalSize)), outputData, 1.0); } #endif + + if (!outputIds) { + if (signedMagnitude) { + float s = -sign(o_color.b - 0.5); + o_color.rg *= s; + o_color.b = s * length; + } + } } \ No newline at end of file