Improved jumpflood

This commit is contained in:
Edwin Jakobs
2019-08-14 15:45:18 +02:00
parent 91487fef7e
commit e2b59059dc
3 changed files with 65 additions and 75 deletions

View File

@@ -5,6 +5,9 @@ import org.openrndr.draw.*
import org.openrndr.filter.blend.passthrough import org.openrndr.filter.blend.passthrough
import org.openrndr.math.Matrix44 import org.openrndr.math.Matrix44
import org.openrndr.resourceUrl import org.openrndr.resourceUrl
import kotlin.math.ceil
import kotlin.math.max
import kotlin.math.pow
class EncodePoints : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/encode-points.frag"))) class EncodePoints : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/encode-points.frag")))
class JumpFlood : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/jumpflood.frag"))) { class JumpFlood : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/jumpflood.frag"))) {
@@ -30,38 +33,26 @@ private val pixelDirection by lazy { PixelDirection() }
private val contourPoints by lazy { ContourPoints() } private val contourPoints by lazy { ContourPoints() }
private val threshold by lazy { Threshold() } private val threshold by lazy { Threshold() }
class JumpFlooder(val width: Int, val height: Int) { class JumpFlooder(val width: Int, val height: Int, format:ColorFormat = ColorFormat.RGB, type:ColorType = ColorType.FLOAT32) {
private val dimension = Math.max(width, height)
private val exp = Math.ceil(Math.log(dimension.toDouble()) / Math.log(2.0)).toInt() private val dimension = max(width, height)
private val squareDim = Math.pow(2.0, exp.toDouble()).toInt() private val exp = ceil(Math.log(dimension.toDouble()) / Math.log(2.0)).toInt()
private val squareDim = 2.0.pow(exp.toDouble()).toInt()
private val coordinates = private val coordinates =
listOf(colorBuffer(squareDim, squareDim, format = ColorFormat.RGB, type = ColorType.FLOAT32), listOf(colorBuffer(squareDim, squareDim, format = format, type = type),
colorBuffer(squareDim, squareDim, format = ColorFormat.RGB, type = ColorType.FLOAT32)) colorBuffer(squareDim, squareDim, format = format, type = type))
private val final = renderTarget(width, height) { private val final = renderTarget(width, height) {
colorBuffer(type = ColorType.FLOAT32) colorBuffer(format = format, type = type)
} }
val encoded: ColorBuffer get() = final.colorBuffer(0) val encoded: ColorBuffer get() = final.colorBuffer(0)
private val square = renderTarget(squareDim, squareDim) { private val square = renderTarget(squareDim, squareDim) {
colorBuffer() colorBuffer(format = format, type = type)
} }
// fun distanceToContour(drawer: Drawer, input: ColorBuffer, thresholdValue: Double = 0.5): ColorBuffer {
// threshold.threshold = thresholdValue
// threshold.apply(input, thresholded)
// contourPoints.apply(thresholded, edges)
// contourUsed = true
// return jumpFlood(drawer, edges)
// }
// fun directions(xRange: IntProgression = 0 until width, yRange: IntProgression = 0 until height): Array<List<Vector2>> {
// result.shadow.download()
// return result.shadow.mapIndexed(xRange, yRange) { _, _, r, g, _, _ -> Vector2(r, g) }
// }
fun jumpFlood(drawer: Drawer, input: ColorBuffer): ColorBuffer { fun jumpFlood(drawer: Drawer, input: ColorBuffer): ColorBuffer {
if (input.width != width || input.height != height) { if (input.width != width || input.height != height) {
throw IllegalArgumentException("dimensions mismatch") throw IllegalArgumentException("dimensions mismatch")
@@ -140,4 +131,3 @@ fun directionFieldFromBitmap(drawer: Drawer, bitmap: ColorBuffer,
jumpFlooder: JumpFlooder? = null, jumpFlooder: JumpFlooder? = null,
result: ColorBuffer? = null result: ColorBuffer? = null
): ColorBuffer = encodeDecodeBitmap(drawer, contourPoints, pixelDirection, bitmap, jumpFlooder, result) ): ColorBuffer = encodeDecodeBitmap(drawer, contourPoints, pixelDirection, bitmap, jumpFlooder, result)

View File

@@ -1,16 +1,16 @@
#version 330 core #version 330 core
uniform sampler2D tex0; uniform sampler2D tex0;
in vec2 v_texCoord0; in vec2 v_texCoord0;
out vec4 o_color; out vec4 o_color;
void main() { void main() {
float ref = texture(tex0, v_texCoord0).r; vec4 t = texture(tex0, v_texCoord0);
vec4 outc = vec4(-1.0, -1.0, 0.0, 1.0); vec4 outc = vec4(-1.0, -1.0, t.r, 1.0);
if (ref > 0.5) { if (t.r > 0.0) {
outc.xy = v_texCoord0.xy; outc.xy = v_texCoord0.xy;
} }
o_color = outc; o_color = outc;
} }

View File

@@ -1,39 +1,39 @@
#version 330 core #version 330 core
in vec2 v_texCoord0; in vec2 v_texCoord0;
uniform sampler2D tex0; uniform sampler2D tex0;
uniform int maxSteps; uniform int maxSteps;
uniform int step; uniform int step;
out vec4 o_color; out vec4 o_color;
void main() { void main() {
float stepwidth = 1.0 / pow(2.0, step+1); float stepwidth = 1.0 / pow(2.0, step+1);
float bestDistance = 9999.0; float bestDistance = 9999.0;
vec2 bestCoord = vec2(-1.0); vec2 bestCoord = vec2(-1.0);
vec2 bestColor = vec2(-1.0); vec2 bestColor = vec2(-1.0);
vec2 is = vec2(1.0) / textureSize(tex0, 0); vec2 is = vec2(1.0) / textureSize(tex0, 0);
float found = 0.0; float found = 0.0;
for (int y = -1; y <= 1; ++y) { for (int y = -1; y <= 1; ++y) {
for (int x = -1; x <= 1; ++x) { for (int x = -1; x <= 1; ++x) {
vec2 sampleCoord = v_texCoord0 + vec2(stepwidth) * vec2(x,y); vec2 sampleCoord = v_texCoord0 + vec2(stepwidth) * vec2(x,y);
vec4 data = texture( tex0, sampleCoord); vec4 data = texture( tex0, sampleCoord);
vec2 seedCoord = data.xy; vec2 seedCoord = data.xy;
vec2 seedColor = data.zw; vec2 seedColor = data.zw;
float dist = length(seedCoord - v_texCoord0); float dist = length(seedCoord - v_texCoord0);
if ((seedCoord.x >= 0.0 || seedCoord.y >= 0.0) && dist < bestDistance) if ((seedCoord.x >= 0.0 || seedCoord.y >= 0.0) && dist < bestDistance)
{ {
found = 1.0; found = 1.0;
bestDistance = dist; bestDistance = dist;
bestCoord = seedCoord; bestCoord = seedCoord;
bestColor = seedColor; bestColor = seedColor;
} }
} }
} }
o_color = vec4(bestCoord, found, 1.0); o_color = vec4(bestCoord, bestColor.r, 1.0);
} }