From dafd309924d0b970eafa3d97252b20be8d4a35e2 Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Tue, 21 Apr 2020 11:44:59 +0200 Subject: [PATCH] Add skeleton filters to orx-jumpflood --- orx-jumpflood/build.gradle | 15 ++++ .../src/demo/kotlin/DemoSkeleton01.kt | 49 +++++++++++ .../src/demo/kotlin/DemoStraightSkeleton01.kt | 48 ++++++++++ .../src/main/kotlin/DistanceField.kt | 5 +- orx-jumpflood/src/main/kotlin/JumpFlood.kt | 19 ++-- orx-jumpflood/src/main/kotlin/fx/InnerGlow.kt | 2 - orx-jumpflood/src/main/kotlin/fx/Inpaint.kt | 7 +- orx-jumpflood/src/main/kotlin/fx/OuterGlow.kt | 3 +- orx-jumpflood/src/main/kotlin/fx/Skeleton.kt | 83 ++++++++++++++++++ .../src/main/kotlin/fx/StraightSkeleton.kt | 87 +++++++++++++++++++ .../resources/shaders/gl3/fx/skeleton.frag | 44 ++++++++++ .../shaders/gl3/fx/straight-skeleton.frag | 48 ++++++++++ .../shaders/gl3/pixel-direction.frag | 13 +-- .../resources/shaders/gl3/pixel-distance.frag | 28 ++++-- 14 files changed, 418 insertions(+), 33 deletions(-) create mode 100644 orx-jumpflood/src/demo/kotlin/DemoSkeleton01.kt create mode 100644 orx-jumpflood/src/demo/kotlin/DemoStraightSkeleton01.kt create mode 100644 orx-jumpflood/src/main/kotlin/fx/Skeleton.kt create mode 100644 orx-jumpflood/src/main/kotlin/fx/StraightSkeleton.kt create mode 100644 orx-jumpflood/src/main/resources/shaders/gl3/fx/skeleton.frag create mode 100644 orx-jumpflood/src/main/resources/shaders/gl3/fx/straight-skeleton.frag diff --git a/orx-jumpflood/build.gradle b/orx-jumpflood/build.gradle index 217cbae4..be8b867e 100644 --- a/orx-jumpflood/build.gradle +++ b/orx-jumpflood/build.gradle @@ -1,3 +1,18 @@ +sourceSets { + demo { + java { + srcDirs = ["src/demo/kotlin"] + compileClasspath += main.getCompileClasspath() + runtimeClasspath += main.getRuntimeClasspath() + } + } +} + dependencies { implementation project(":orx-fx") + demoImplementation project(":orx-noise") + demoImplementation("org.openrndr:openrndr-core:$openrndrVersion") + demoRuntimeOnly("org.openrndr:openrndr-gl3:$openrndrVersion") + demoRuntimeOnly("org.openrndr:openrndr-gl3-natives-$openrndrOS:$openrndrVersion") + demoImplementation(sourceSets.getByName("main").output) } \ No newline at end of file diff --git a/orx-jumpflood/src/demo/kotlin/DemoSkeleton01.kt b/orx-jumpflood/src/demo/kotlin/DemoSkeleton01.kt new file mode 100644 index 00000000..6fbd4394 --- /dev/null +++ b/orx-jumpflood/src/demo/kotlin/DemoSkeleton01.kt @@ -0,0 +1,49 @@ +package sketches + +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.ColorType + +import org.openrndr.draw.isolatedWithTarget +import org.openrndr.draw.renderTarget +import org.openrndr.extra.jumpfill.fx.Skeleton +import org.openrndr.extra.jumpfill.fx.StraightSkeleton +import org.openrndr.extra.noise.simplex + +fun main() { + application { + configure { + width = 1280 + height = 720 + } + program { + val skeleton = Skeleton() + + val input = renderTarget(width, height) { + colorBuffer() + } + val field = input.colorBuffer(0).createEquivalent(type = ColorType.FLOAT32) + extend { + drawer.isolatedWithTarget(input) { + // -- draw something interesting + drawer.stroke = null + drawer.background(ColorRGBa.BLACK) + drawer.fill = ColorRGBa.WHITE + drawer.circle(mouse.position, 300.0) + drawer.fill = ColorRGBa.BLACK + drawer.circle(mouse.position, 150.0) + drawer.fill = ColorRGBa.WHITE + for (i in 0 until 30) { + val time = seconds * 0.25 + val x = simplex(i * 20, time) * width / 2 + width / 2 + val y = simplex(i * 20 + 5, time) * height / 2 + height / 2 + val r = simplex(i*30, time) * 50.0 + 50.0 + drawer.circle(x, y, r) + } + } + skeleton.apply(input.colorBuffer(0), field) + drawer.image(field) + } + } + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/demo/kotlin/DemoStraightSkeleton01.kt b/orx-jumpflood/src/demo/kotlin/DemoStraightSkeleton01.kt new file mode 100644 index 00000000..e8b3dbef --- /dev/null +++ b/orx-jumpflood/src/demo/kotlin/DemoStraightSkeleton01.kt @@ -0,0 +1,48 @@ +package sketches + +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.ColorType + +import org.openrndr.draw.isolatedWithTarget +import org.openrndr.draw.renderTarget +import org.openrndr.extra.jumpfill.fx.StraightSkeleton +import org.openrndr.extra.noise.simplex + +fun main() { + application { + configure { + width = 1280 + height = 720 + } + program { + val straightSkeleton = StraightSkeleton() + + val input = renderTarget(width, height) { + colorBuffer() + } + val field = input.colorBuffer(0).createEquivalent(type = ColorType.FLOAT32) + extend { + drawer.isolatedWithTarget(input) { + // -- draw something interesting + drawer.stroke = null + drawer.background(ColorRGBa.BLACK) + drawer.fill = ColorRGBa.WHITE + drawer.circle(mouse.position, 300.0) + drawer.fill = ColorRGBa.BLACK + drawer.circle(mouse.position, 150.0) + drawer.fill = ColorRGBa.WHITE + for (i in 0 until 30) { + val time = seconds * 0.25 + val x = simplex(i * 20, time) * width / 2 + width / 2 + val y = simplex(i * 20 + 5, time) * height / 2 + height / 2 + val r = simplex(i*30, time) * 50.0 + 50.0 + drawer.circle(x, y, r) + } + } + straightSkeleton.apply(input.colorBuffer(0), field) + drawer.image(field) + } + } + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/kotlin/DistanceField.kt b/orx-jumpflood/src/main/kotlin/DistanceField.kt index 741216bf..81ef3a07 100644 --- a/orx-jumpflood/src/main/kotlin/DistanceField.kt +++ b/orx-jumpflood/src/main/kotlin/DistanceField.kt @@ -24,6 +24,8 @@ class DistanceField : Filter() { private val decodeFilter = PixelDistance() + var signedDistance = false + override fun apply(source: Array, target: Array) { if (thresholded == null) { thresholded = colorBuffer(target[0].width, target[0].height, format = ColorFormat.R) @@ -38,10 +40,11 @@ class DistanceField : Filter() { thresholdFilter.apply(source[0], thresholded!!) contourFilter.apply(thresholded!!, contoured!!) val result = jumpFlooder!!.jumpFlood(contoured!!) + decodeFilter.signedDistance = signedDistance decodeFilter.originalSize = Vector2(target[0].width * 1.0, target[0].height * 1.0) decodeFilter.distanceScale = distanceScale decodeFilter.signedBit = false - decodeFilter.apply(result, result) + decodeFilter.apply(arrayOf(result, thresholded!!), arrayOf(result)) result.copyTo(target[0]) } } \ No newline at end of file diff --git a/orx-jumpflood/src/main/kotlin/JumpFlood.kt b/orx-jumpflood/src/main/kotlin/JumpFlood.kt index c59e9522..18896523 100644 --- a/orx-jumpflood/src/main/kotlin/JumpFlood.kt +++ b/orx-jumpflood/src/main/kotlin/JumpFlood.kt @@ -42,10 +42,12 @@ class PixelDistance : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/pixel var distanceScale: Double by parameters var originalSize: Vector2 by parameters var signedBit: Boolean by parameters + var signedDistance: Boolean by parameters init { distanceScale = 1.0 originalSize = Vector2(512.0, 512.0) signedBit = true + signedDistance = false } } @@ -120,7 +122,7 @@ class JumpFlooder(val width: Int, val height: Int, format: ColorFormat = ColorFo } } -private fun encodeDecodeBitmap(drawer: Drawer, preprocess: Filter, decoder: Filter, bitmap: ColorBuffer, +private fun encodeDecodeBitmap(preprocess: Filter, decoder: Filter, bitmap: ColorBuffer, jumpFlooder: JumpFlooder? = null, result: ColorBuffer? = null ): ColorBuffer { @@ -136,7 +138,6 @@ private fun encodeDecodeBitmap(drawer: Drawer, preprocess: Filter, decoder: Filt if (jumpFlooder == null) { _jumpFlooder.destroy() } - return _result } @@ -144,19 +145,17 @@ private fun encodeDecodeBitmap(drawer: Drawer, preprocess: Filter, decoder: Filt * Creates a color buffer containing the coordinates of the nearest centroids * @param bitmap a ColorBuffer with centroids in red (> 0) */ -fun centroidsFromBitmap(drawer: Drawer, bitmap: ColorBuffer, +fun centroidsFromBitmap(bitmap: ColorBuffer, jumpFlooder: JumpFlooder? = null, result: ColorBuffer? = null -): ColorBuffer = encodeDecodeBitmap(drawer, passthrough, passthrough, bitmap, jumpFlooder, result) +): ColorBuffer = encodeDecodeBitmap(passthrough, passthrough, bitmap, jumpFlooder, result) -fun distanceFieldFromBitmap(drawer: Drawer, bitmap: ColorBuffer, +fun distanceFieldFromBitmap(bitmap: ColorBuffer, jumpFlooder: JumpFlooder? = null, result: ColorBuffer? = null -): ColorBuffer = encodeDecodeBitmap(drawer, contourPoints, pixelDistance, bitmap, jumpFlooder, result) +): ColorBuffer = encodeDecodeBitmap(contourPoints, pixelDistance, bitmap, jumpFlooder, result) -fun directionFieldFromBitmap(drawer: Drawer, bitmap: ColorBuffer, +fun directionFieldFromBitmap(bitmap: ColorBuffer, jumpFlooder: JumpFlooder? = null, result: ColorBuffer? = null -): ColorBuffer = encodeDecodeBitmap(drawer, contourPoints, pixelDirection, bitmap, jumpFlooder, result) - - +): ColorBuffer = encodeDecodeBitmap(contourPoints, pixelDirection, bitmap, jumpFlooder, result) \ No newline at end of file diff --git a/orx-jumpflood/src/main/kotlin/fx/InnerGlow.kt b/orx-jumpflood/src/main/kotlin/fx/InnerGlow.kt index 5b381ea2..adf7fe8a 100644 --- a/orx-jumpflood/src/main/kotlin/fx/InnerGlow.kt +++ b/orx-jumpflood/src/main/kotlin/fx/InnerGlow.kt @@ -47,14 +47,12 @@ class InnerGlow : Filter() { @DoubleParameter("image opacity", 0.0, 1.0) var imageOpacity = 1.0 - @ColorParameter("color") var color = ColorRGBa.WHITE private var jumpFlooder: JumpFlooder? = null private val decodeFilter = PixelDirection() private val glowFilter = InnerGlowFilter() - private var distance: ColorBuffer? = null override fun apply(source: Array, target: Array) { diff --git a/orx-jumpflood/src/main/kotlin/fx/Inpaint.kt b/orx-jumpflood/src/main/kotlin/fx/Inpaint.kt index f8b1ea47..0fe27f80 100644 --- a/orx-jumpflood/src/main/kotlin/fx/Inpaint.kt +++ b/orx-jumpflood/src/main/kotlin/fx/Inpaint.kt @@ -13,9 +13,10 @@ private class InpaintFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/g var noise: Double by parameters var imageOpacity: Double by parameters - var opacity : Double by parameters - var shape : Double by parameters + var opacity: Double by parameters + var shape: Double by parameters var width: Double by parameters + init { noise = 0.0 imageOpacity = 1.0 @@ -33,7 +34,6 @@ class Inpaint : Filter() { @DoubleParameter("noise", 0.0, 1.0) var noise = 0.1 - @DoubleParameter("opacity", 0.0, 1.0) var opacity = 1.0 @@ -43,7 +43,6 @@ class Inpaint : Filter() { @DoubleParameter("shape", 0.0, 10.0) var shape = 0.0 - private var jumpFlooder: JumpFlooder? = null private val decodeFilter = PixelDirection() private val inpaintFilter = InpaintFilter() diff --git a/orx-jumpflood/src/main/kotlin/fx/OuterGlow.kt b/orx-jumpflood/src/main/kotlin/fx/OuterGlow.kt index 5b66edc5..a48af6a1 100644 --- a/orx-jumpflood/src/main/kotlin/fx/OuterGlow.kt +++ b/orx-jumpflood/src/main/kotlin/fx/OuterGlow.kt @@ -47,13 +47,12 @@ class OuterGlow : Filter() { @DoubleParameter("image opacity", 0.0, 1.0) var imageOpacity = 1.0 - @ColorParameter("color") var color = ColorRGBa.WHITE private var jumpFlooder: JumpFlooder? = null private val decodeFilter = PixelDirection() - private val glowFilter = org.openrndr.extra.jumpfill.fx.OuterGlowFilter() + private val glowFilter = OuterGlowFilter() private var distance: ColorBuffer? = null diff --git a/orx-jumpflood/src/main/kotlin/fx/Skeleton.kt b/orx-jumpflood/src/main/kotlin/fx/Skeleton.kt new file mode 100644 index 00000000..33bc1e94 --- /dev/null +++ b/orx-jumpflood/src/main/kotlin/fx/Skeleton.kt @@ -0,0 +1,83 @@ +package org.openrndr.extra.jumpfill.fx + +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.* +import org.openrndr.extra.jumpfill.* +import org.openrndr.extra.parameters.ColorParameter + +import org.openrndr.extra.parameters.Description +import org.openrndr.extra.parameters.DoubleParameter +import org.openrndr.math.Vector2 +import org.openrndr.resourceUrl + +private class SkeletonFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/fx/skeleton.frag"))) { + var skeletonColor: ColorRGBa by parameters + var foregroundColor: ColorRGBa by parameters + var backgroundColor: ColorRGBa by parameters + + init { + skeletonColor = ColorRGBa.WHITE + foregroundColor = ColorRGBa.GRAY + backgroundColor = ColorRGBa.TRANSPARENT + } +} + +@Description("Skeleton") +class Skeleton : Filter() { + @DoubleParameter("threshold", 0.0, 1.0, order = 0) + var threshold = 0.5 + + @DoubleParameter("distance scale", 0.0, 1.0, order = 1) + var distanceScale = 1.0 + + @ColorParameter("skeleton color", order = 2) + var skeletonColor = ColorRGBa.WHITE + + @ColorParameter("foreground color", order = 3) + var foregroundColor = ColorRGBa.GRAY + + @ColorParameter("background color", order = 4) + var backgroundColor = ColorRGBa.TRANSPARENT + + private val thresholdFilter = Threshold() + private var thresholded: ColorBuffer? = null + private val contourFilter = ContourPoints() + private var contoured: ColorBuffer? = null + private var copied: ColorBuffer? = null + private var jumpFlooder: JumpFlooder? = null + + private val decodeFilter = PixelDistance() + private val skeletonFilter = SkeletonFilter() + + override fun apply(source: Array, target: Array) { + if (thresholded == null) { + thresholded = colorBuffer(target[0].width, target[0].height, format = ColorFormat.R) + } + if (contoured == null) { + contoured = colorBuffer(target[0].width, target[0].height, format = ColorFormat.R) + } + if (jumpFlooder == null) { + jumpFlooder = JumpFlooder(target[0].width, target[0].height) + } + if (copied == null) { + copied = target[0].createEquivalent(type = ColorType.FLOAT32) + } + + thresholdFilter.threshold = threshold + thresholdFilter.apply(source[0], thresholded!!) + contourFilter.apply(thresholded!!, contoured!!) + val result = jumpFlooder!!.jumpFlood(contoured!!) + + decodeFilter.signedDistance = true + decodeFilter.originalSize = Vector2(target[0].width * 1.0, target[0].height * 1.0) + decodeFilter.distanceScale = distanceScale + decodeFilter.signedBit = false + decodeFilter.apply(arrayOf(result, thresholded!!), arrayOf(result)) + + result.copyTo(copied!!) + skeletonFilter.skeletonColor = skeletonColor + skeletonFilter.backgroundColor = backgroundColor + skeletonFilter.foregroundColor = foregroundColor + skeletonFilter.apply(copied!!, target[0]) + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/kotlin/fx/StraightSkeleton.kt b/orx-jumpflood/src/main/kotlin/fx/StraightSkeleton.kt new file mode 100644 index 00000000..54805a71 --- /dev/null +++ b/orx-jumpflood/src/main/kotlin/fx/StraightSkeleton.kt @@ -0,0 +1,87 @@ +package org.openrndr.extra.jumpfill.fx + +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.* +import org.openrndr.extra.jumpfill.* +import org.openrndr.extra.parameters.ColorParameter + +import org.openrndr.extra.parameters.Description +import org.openrndr.extra.parameters.DoubleParameter +import org.openrndr.math.Vector2 +import org.openrndr.resourceUrl +import kotlin.math.sqrt + +private class StraightSkeletonFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/fx/straight-skeleton.frag"))) { + var angleThreshold: Double by parameters + var skeletonColor: ColorRGBa by parameters + var foregroundColor: ColorRGBa by parameters + var backgroundColor: ColorRGBa by parameters + + init { + skeletonColor = ColorRGBa.WHITE + foregroundColor = ColorRGBa.GRAY + backgroundColor = ColorRGBa.TRANSPARENT + angleThreshold = sqrt(2.0) / 2.0; + } +} + +@Description("Skeleton") +class StraightSkeleton : Filter() { + @DoubleParameter("threshold", 0.0, 1.0, order = 0) + var threshold = 0.5 + + @DoubleParameter("distance scale", 0.0, 1.0, order = 1) + var distanceScale = 1.0 + + @DoubleParameter("angle threshold", 0.0, 1.0, order = 2) + var angleThreshold = sqrt(2.0) / 2.0 + + @ColorParameter("skeleton color", order = 3) + var skeletonColor = ColorRGBa.WHITE + + @ColorParameter("foreground color", order = 4) + var foregroundColor = ColorRGBa.GRAY + + @ColorParameter("background color", order = 5) + var backgroundColor = ColorRGBa.TRANSPARENT + + private val thresholdFilter = Threshold() + private var thresholded: ColorBuffer? = null + private val contourFilter = ContourPoints() + private var contoured: ColorBuffer? = null + private var copied: ColorBuffer? = null + private var jumpFlooder: JumpFlooder? = null + + private val decodeFilter = PixelDirection() + private val skeletonFilter = StraightSkeletonFilter() + + override fun apply(source: Array, target: Array) { + if (thresholded == null) { + thresholded = colorBuffer(target[0].width, target[0].height, format = ColorFormat.R) + } + if (contoured == null) { + contoured = colorBuffer(target[0].width, target[0].height, format = ColorFormat.R) + } + if (jumpFlooder == null) { + jumpFlooder = JumpFlooder(target[0].width, target[0].height) + } + if (copied == null) { + copied = target[0].createEquivalent(type = ColorType.FLOAT32) + } + + thresholdFilter.threshold = threshold + thresholdFilter.apply(source[0], thresholded!!) + contourFilter.apply(thresholded!!, contoured!!) + val result = jumpFlooder!!.jumpFlood(contoured!!) + decodeFilter.originalSize = Vector2(target[0].width * 1.0, target[0].height * 1.0) + decodeFilter.distanceScale = distanceScale + decodeFilter.apply(arrayOf(result, thresholded!!), arrayOf(result)) + result.copyTo(copied!!) + + skeletonFilter.angleThreshold = angleThreshold + skeletonFilter.skeletonColor = skeletonColor + skeletonFilter.backgroundColor = backgroundColor + skeletonFilter.foregroundColor = foregroundColor + skeletonFilter.apply(copied!!, target[0]) + } +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/fx/skeleton.frag b/orx-jumpflood/src/main/resources/shaders/gl3/fx/skeleton.frag new file mode 100644 index 00000000..0bf23f27 --- /dev/null +++ b/orx-jumpflood/src/main/resources/shaders/gl3/fx/skeleton.frag @@ -0,0 +1,44 @@ +#version 330 core + +uniform sampler2D tex0;// signed distance +uniform vec4 skeletonColor; +uniform vec4 backgroundColor; +uniform vec4 foregroundColor; +uniform float angleTreshold; + +in vec2 v_texCoord0; + +out vec4 o_color; + +void main() { + float centerDistance = texture(tex0, v_texCoord0).r; + vec2 step = 1.0 / textureSize(tex0, 0); + + float minDistance = 1000.0; + + float nd = texture(tex0, v_texCoord0 + step * vec2(0.0, -1.0)).r; + float ed = texture(tex0, v_texCoord0 + step * vec2(1.0, 0.0)).r; + float wd = texture(tex0, v_texCoord0 + step * vec2(-1.0, 0.0)).r; + float sd = texture(tex0, v_texCoord0 + step * vec2(0.0, 1.0)).r; + + float nd2 = texture(tex0, v_texCoord0 + step * vec2(-1.0, -1.0)).r; + float ed2 = texture(tex0, v_texCoord0 + step * vec2(-1.0, 1.0)).r; + float wd2 = texture(tex0, v_texCoord0 + step * vec2(1.0, -1.0)).r; + float sd2 = texture(tex0, v_texCoord0 + step * vec2(1.0, 1.0)).r; + + float r = -centerDistance * 8.0 + nd + ed + wd + sd + nd2 + ed2 + wd2 + sd2; + + vec4 fc = vec4(0.0); + + if (centerDistance < 0.0) { + fc += foregroundColor * foregroundColor.a; + } else { + fc += backgroundColor * backgroundColor.a; + } + + if (r > 0.0 && centerDistance < 0.0) { + fc = fc * (1.0 - skeletonColor.a) + (skeletonColor * skeletonColor.a); + } + + o_color = fc; +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/fx/straight-skeleton.frag b/orx-jumpflood/src/main/resources/shaders/gl3/fx/straight-skeleton.frag new file mode 100644 index 00000000..ebf563ec --- /dev/null +++ b/orx-jumpflood/src/main/resources/shaders/gl3/fx/straight-skeleton.frag @@ -0,0 +1,48 @@ +#version 330 core + +uniform sampler2D tex0;// signed distance +uniform vec4 skeletonColor; +uniform vec4 backgroundColor; +uniform vec4 foregroundColor; +uniform float angleTreshold; + +in vec2 v_texCoord0; + +out vec4 o_color; + +void main() { + vec4 ct = texture(tex0, v_texCoord0); + vec2 cd = normalize(ct.xy); + vec2 step = 1.0 / textureSize(tex0, 0); + + float minDistance = 1000.0; + + vec4 nt = texture(tex0, v_texCoord0 + step * vec2(0.0, -1.0)); + vec2 nd = normalize(nt.xy); + vec4 et = texture(tex0, v_texCoord0 + step * vec2(1.0, 0.0)); + vec2 ed = normalize(et.xy); + vec4 wt = texture(tex0, v_texCoord0 + step * vec2(-1.0, 0.0)); + vec2 wd = normalize(wt.xy); + vec4 st = texture(tex0, v_texCoord0 + step * vec2(0.0, 1.0)); + vec2 sd = normalize(st.xy); + + float d0 = dot(cd, nd); + float d1 = dot(cd, ed); + float d2 = dot(cd, wd); + float d3 = dot(cd, sd); + + float r = (d0+d1+d2+d3); + + vec4 fc = vec4(0.0); + + if (ct.z > 0.0) { + fc += foregroundColor * foregroundColor.a; + } else { + fc += backgroundColor * backgroundColor.a; + } + + if ((d0 < angleTreshold || d1 < angleTreshold || d2 < angleTreshold || d3 < angleTreshold) && ct.z > 0.0 && length(ct.xy) > 4) { + fc = fc * (1.0 - skeletonColor.a) + (skeletonColor * skeletonColor.a); + } + o_color = fc; +} \ No newline at end of file diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/pixel-direction.frag b/orx-jumpflood/src/main/resources/shaders/gl3/pixel-direction.frag index 852654fd..14992436 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/pixel-direction.frag +++ b/orx-jumpflood/src/main/resources/shaders/gl3/pixel-direction.frag @@ -10,11 +10,14 @@ in vec2 v_texCoord0; out vec4 o_color; void main() { - vec2 size = textureSize(tex0, 0); - vec2 fixUp = v_texCoord0; - vec2 pixelPosition = fixUp; + vec2 sizeDF = textureSize(tex0, 0); // this is always square + vec2 sizeTF = textureSize(tex1, 0); // this can be non-square + + vec2 pixelPosition = v_texCoord0; vec2 centroidPixelPosition = texture(tex0, v_texCoord0).xy; - vec2 pixelDistance = (centroidPixelPosition - pixelPosition) * size * vec2(1.0, -1.0); - float threshold = texture(tex1, v_texCoord0).r; + vec2 pixelDistance = (centroidPixelPosition - pixelPosition) * sizeDF * vec2(1.0, -1.0); + vec2 dfTf = sizeDF / sizeTF; // texture adjusment factor + float threshold = texture(tex1, v_texCoord0 * dfTf).r; + o_color = vec4(pixelDistance * distanceScale, threshold, 1.0); } \ No newline at end of file diff --git a/orx-jumpflood/src/main/resources/shaders/gl3/pixel-distance.frag b/orx-jumpflood/src/main/resources/shaders/gl3/pixel-distance.frag index 0523e12f..daa5ebe9 100644 --- a/orx-jumpflood/src/main/resources/shaders/gl3/pixel-distance.frag +++ b/orx-jumpflood/src/main/resources/shaders/gl3/pixel-distance.frag @@ -6,24 +6,34 @@ uniform sampler2D tex1; uniform vec2 originalSize; uniform float distanceScale; uniform bool signedBit; +uniform bool signedDistance; in vec2 v_texCoord0; out vec4 o_color; void main() { - vec2 size = textureSize(tex0, 0); - vec2 fixUp = v_texCoord0; + vec2 sizeDF = textureSize(tex0, 0); // this is always square + vec2 sizeTF = textureSize(tex1, 0); // this can be non-square - - - vec2 pixelPosition = fixUp; + vec2 pixelPosition = v_texCoord0; vec2 centroidPixelPosition = texture(tex0, v_texCoord0).xy; - vec2 pixelDistance = (centroidPixelPosition - pixelPosition) * size * vec2(1.0, -1.0); - float threshold = texture(tex1, v_texCoord0).r; + vec2 pixelDistance = (centroidPixelPosition - pixelPosition) * sizeDF * vec2(1.0, -1.0); + + vec2 dfTf = sizeDF / sizeTF; // texture adjusment factor + + float threshold = texture(tex1, v_texCoord0 * dfTf).r; + float distance = length(pixelDistance) * distanceScale; + + if (signedDistance) { + if (threshold > 0.5) { + distance *= -1.0; + } + } + if (signedBit) { - o_color = vec4(length(pixelDistance)* distanceScale, threshold, 0.0, 1.0); + o_color = vec4(distance, threshold, 0.0, 1.0); } else { - o_color = vec4(vec3(length(pixelDistance) * distanceScale), 1.0); + o_color = vec4(vec3(distance), 1.0); } } \ No newline at end of file