[orx-fx] Add DirectionalBlur
This commit is contained in:
53
orx-fx/src/commonMain/kotlin/blur/DirectionalBlur.kt
Normal file
53
orx-fx/src/commonMain/kotlin/blur/DirectionalBlur.kt
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package org.openrndr.extra.fx.blur
|
||||||
|
|
||||||
|
import org.openrndr.draw.*
|
||||||
|
import org.openrndr.extra.fx.fx_directional_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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directional blur filter. Takes source image and direction buffer inputs
|
||||||
|
*/
|
||||||
|
@Description("Directional blur")
|
||||||
|
class DirectionalBlur : Filter(mppFilterShader(fx_directional_blur, "directional-blur")) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sample window, default is 5
|
||||||
|
*/
|
||||||
|
@IntParameter("window size", 1, 25)
|
||||||
|
var window: Int by parameters
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spread multiplier, default is 1.0
|
||||||
|
*/
|
||||||
|
@DoubleParameter("kernel spread", 1.0, 4.0)
|
||||||
|
var spread: Double by parameters
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post-blur gain, default is 1.0
|
||||||
|
*/
|
||||||
|
@DoubleParameter("gain", 0.0, 4.0)
|
||||||
|
var gain: Double by parameters
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should filter use directions perpendicular to those in the direction buffer?
|
||||||
|
*/
|
||||||
|
@BooleanParameter("perpendicular")
|
||||||
|
var perpendicular: Boolean by parameters
|
||||||
|
|
||||||
|
init {
|
||||||
|
window = 5
|
||||||
|
spread = 1.0
|
||||||
|
gain = 1.0
|
||||||
|
perpendicular = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun apply(source: Array<ColorBuffer>, target: Array<ColorBuffer>) {
|
||||||
|
parameters["wrapX"] = false
|
||||||
|
parameters["wrapY"] = false
|
||||||
|
super.apply(source, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
38
orx-fx/src/demo/kotlin/DemoDirectionalBlur01.kt
Normal file
38
orx-fx/src/demo/kotlin/DemoDirectionalBlur01.kt
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import org.openrndr.application
|
||||||
|
import org.openrndr.color.ColorRGBa
|
||||||
|
import org.openrndr.draw.*
|
||||||
|
import org.openrndr.extra.fx.blur.DirectionalBlur
|
||||||
|
import org.openrndr.math.smoothstep
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
fun main() = application {
|
||||||
|
program {
|
||||||
|
val db = DirectionalBlur()
|
||||||
|
val rt = renderTarget(width, height) {
|
||||||
|
colorBuffer()
|
||||||
|
}
|
||||||
|
|
||||||
|
val blurred = colorBuffer(width, height)
|
||||||
|
val direction = colorBuffer(width, height, type = ColorType.FLOAT32)
|
||||||
|
val s = direction.shadow
|
||||||
|
for (y in 0 until height) {
|
||||||
|
for (x in 0 until width) {
|
||||||
|
val a = smoothstep(0.45, 0.55, cos((x + y) * 0.01) * 0.5 + 0.5)
|
||||||
|
s[x, y] = ColorRGBa(cos(y * .1) * a, sin(x * 0.1) * a, 0.0, 1.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.upload()
|
||||||
|
val image = loadImage("demo-data/images/image-001.png")
|
||||||
|
extend {
|
||||||
|
drawer.isolatedWithTarget(rt) {
|
||||||
|
clear(ColorRGBa.BLACK)
|
||||||
|
drawer.image(image)
|
||||||
|
}
|
||||||
|
db.window = 10
|
||||||
|
db.apply(arrayOf(rt.colorBuffer(0), direction), blurred)
|
||||||
|
drawer.image(blurred)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
67
orx-fx/src/shaders/glsl/blur/directional-blur.frag
Normal file
67
orx-fx/src/shaders/glsl/blur/directional-blur.frag
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#ifdef OR_IN_OUT
|
||||||
|
in vec2 v_texCoord0;
|
||||||
|
#else
|
||||||
|
varying vec2 v_texCoord0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform sampler2D tex0; // image
|
||||||
|
uniform sampler2D tex1; // blurDirection
|
||||||
|
uniform vec2 textureSize0;
|
||||||
|
|
||||||
|
uniform int window;
|
||||||
|
uniform float sigma;
|
||||||
|
uniform float gain;
|
||||||
|
uniform vec4 subtract;
|
||||||
|
uniform float spread;
|
||||||
|
|
||||||
|
uniform bool wrapX;
|
||||||
|
uniform bool wrapY;
|
||||||
|
uniform bool perpendicular;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OR_GL_FRAGCOLOR
|
||||||
|
out vec4 o_color;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec2 wrap(vec2 uv) {
|
||||||
|
vec2 res = uv;
|
||||||
|
if (wrapX) {
|
||||||
|
res.x = mod(res.x, 1.0);
|
||||||
|
}
|
||||||
|
if (wrapY) {
|
||||||
|
res.y = mod(res.y, 1.0);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
void main() {
|
||||||
|
vec2 s = textureSize0;
|
||||||
|
s = vec2(1.0 / s.x, 1.0 / s.y);
|
||||||
|
|
||||||
|
|
||||||
|
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
#ifndef OR_GL_TEXTURE2D
|
||||||
|
vec2 blurDirection = texture(tex1, v_texCoord0).xy;
|
||||||
|
if (perpendicular) {
|
||||||
|
blurDirection = vec2(-blurDirection.y, blurDirection.x);
|
||||||
|
}
|
||||||
|
float weight = 0.0;
|
||||||
|
for (int x = 0; x < window; ++x) {
|
||||||
|
sum += texture(tex0, wrap(v_texCoord0 + float(x) * blurDirection * s * spread));
|
||||||
|
weight += 1.0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
vec2 blurDirection = texture2D(tex1, v_texCoord0);
|
||||||
|
float weight = 0.0;
|
||||||
|
sum += texture2D(tex0, wrap(v_texCoord0 * blurDirection * s * spread));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
vec4 result = (sum/weight) * gain;
|
||||||
|
#ifdef OR_GL_FRAGCOLOR
|
||||||
|
gl_FragColor = result;
|
||||||
|
#else
|
||||||
|
o_color = result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user