Add distance-transform based Inpaint

This commit is contained in:
Edwin Jakobs
2020-03-14 11:43:56 +01:00
parent 8e94094d05
commit 9666134207
4 changed files with 124 additions and 3 deletions

View File

@@ -30,7 +30,7 @@ private class InnerGlowFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders
}
}
@Description("Outer glow")
@Description("Inner glow")
class InnerGlow : Filter() {
@DoubleParameter("width", 0.0, 50.0)
var width = 5.0

View File

@@ -0,0 +1,72 @@
package org.openrndr.extra.jumpfill.fx
import org.openrndr.draw.*
import org.openrndr.extra.jumpfill.EncodeSubpixel
import org.openrndr.extra.jumpfill.JumpFlooder
import org.openrndr.extra.jumpfill.PixelDirection
import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.math.Vector2
import org.openrndr.resourceUrl
private class InpaintFilter : Filter(filterShaderFromUrl(resourceUrl("/shaders/gl3/fx/inpaint.frag"))) {
var noise: Double by parameters
var imageOpacity: 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
opacity = 1.0
shape = 0.0
width = 0.5
}
}
@Description("Inpaint")
class Inpaint : Filter() {
@DoubleParameter("width", 0.0, 1.0)
var width = 0.5
@DoubleParameter("noise", 0.0, 1.0)
var noise = 0.1
@DoubleParameter("opacity", 0.0, 1.0)
var opacity = 1.0
@DoubleParameter("image opacity", 0.0, 1.0)
var imageOpacity = 1.0
@DoubleParameter("shape", 0.0, 10.0)
var shape = 0.0
private var jumpFlooder: JumpFlooder? = null
private val decodeFilter = PixelDirection()
private val inpaintFilter = InpaintFilter()
private var distance: ColorBuffer? = null
override fun apply(source: Array<ColorBuffer>, target: Array<ColorBuffer>) {
if (jumpFlooder == null) {
jumpFlooder = JumpFlooder(target[0].width, target[0].height, encodePoints = EncodeSubpixel())
}
if (distance == null) {
distance = colorBuffer(target[0].width, target[0].height, type = ColorType.FLOAT32)
}
val result = jumpFlooder!!.jumpFlood(source[0])
decodeFilter.originalSize = Vector2(target[0].width * 1.0, target[0].height * 1.0)
decodeFilter.distanceScale = 1.0
decodeFilter.apply(result, result)
result.copyTo(distance!!)
inpaintFilter.noise = noise
inpaintFilter.imageOpacity = imageOpacity
inpaintFilter.opacity = opacity
inpaintFilter.shape = shape
inpaintFilter.width = width
inpaintFilter.apply(arrayOf(source[0], distance!!), target[0])
}
}

View File

@@ -19,7 +19,7 @@ void main() {
float ref = step(threshold, texture(tex0, v_texCoord0).a);
vec2 o = stepSize/2.0;
vec2 o = vec2(0.0); //stepSize/2.0;
float t00 = texture(tex0, v_texCoord0 + o + vec2(0.0, 0.0)).a;
float t10 = texture(tex0, v_texCoord0 + o + vec2(stepSize.x, 0.0)).a;
float t01 = texture(tex0, v_texCoord0 + o + vec2(0.0, stepSize.y)).a;
@@ -117,7 +117,7 @@ void main() {
//float contour = (mask == 14 || mask == 11 || mask == 7 || mask == 13) ? 1.0 : 0.0;
if (contour > 0.0) {
o_color = vec4(v_texCoord0 + offset*stepSize , ref, 1.0);
o_color = vec4(v_texCoord0 /*+ offset*stepSize*/ , ref, 1.0);
} else {
o_color = vec4(-1.0, -1.0, 0.0, 1.0);
}

View File

@@ -0,0 +1,49 @@
#version 330 core
uniform sampler2D tex0;// image
uniform sampler2D tex1;// distance
uniform float width;
uniform float noise;
uniform float shape;
uniform float imageOpacity;
uniform float opacity;
in vec2 v_texCoord0;
out vec4 o_color;
#define HASHSCALE 443.8975
vec2 hash22(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * HASHSCALE);
p3 += dot(p3, p3.yzx+19.19);
return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));
}
void main() {
vec4 original = texture(tex0, v_texCoord0);
vec2 ts = textureSize(tex0, 0);
vec2 step = 1.0 / ts;
vec2 distance = texture(tex1, v_texCoord0).rg;
vec2 n = normalize(distance);
vec2 uvOff = distance * step * vec2(1.0, -1.0);
vec4 border = vec4(0.0);
float w = 0.0;
for (int j = -1; j <= 1; ++j) {
for (int i = -1; i <= 1; ++i) {
vec4 smp = texture(tex0, v_texCoord0 + uvOff + step * vec2(i, j));
border += smp;
}
}
vec4 nborder = border.a>0.0?vec4(border.rgb/border.a, 1.0):vec4(0.0);
float d = length(distance);
vec2 h = hash22(v_texCoord0)*10.0;
float rwidth = max(ts.x, ts.y) * width;
float e = shape > 0.0 ? exp(-( pow((d+h.x*noise)*1.0/rwidth, shape))) : 1.0;
o_color = original * imageOpacity + (1.0-original.a)* nborder * e * opacity;
}