Add LaserBlur

This commit is contained in:
Edwin Jakobs
2020-05-03 18:38:33 +02:00
parent bade284622
commit cee3e1fd14
5 changed files with 236 additions and 2 deletions

View File

@@ -10,9 +10,11 @@ sourceSets {
dependencies {
api project(":orx-parameters")
implementation project(":orx-noise")
demoImplementation("org.openrndr:openrndr-core:$openrndrVersion")
demoImplementation("org.openrndr:openrndr-extensions:$openrndrVersion")
demoImplementation(project(":orx-gui"))
demoImplementation(project(":orx-compositor"))
demoRuntimeOnly("org.openrndr:openrndr-gl3:$openrndrVersion")
demoRuntimeOnly("org.openrndr:openrndr-gl3-natives-$openrndrOS:$openrndrVersion")
demoImplementation(sourceSets.getByName("main").output)

View File

@@ -0,0 +1,64 @@
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extensions.SingleScreenshot
import org.openrndr.extra.compositor.compose
import org.openrndr.extra.compositor.draw
import org.openrndr.extra.compositor.layer
import org.openrndr.extra.compositor.post
import org.openrndr.extra.fx.blur.GaussianBloom
import org.openrndr.extra.fx.blur.LaserBlur
import org.openrndr.extra.gui.GUI
import org.openrndr.extra.gui.addTo
import org.openrndr.extra.noise.simplex
import org.openrndr.math.Vector2
import kotlin.math.absoluteValue
fun main() = application {
configure {
width = 1280
height = 720
}
program {
if (System.getProperty("takeScreenshot") == "true") {
extend(SingleScreenshot()) {
this.outputFile = System.getProperty("screenshotPath")
}
}
val gui = GUI()
val c = compose {
layer {
draw {
drawer.fill = null
drawer.strokeWeight = 4.0
drawer.translate(width/2.0, height/2.0)
drawer.rotate(seconds*45.0 + simplex(0, seconds)*45.0)
drawer.translate(-width/2.0, -height/2.0)
for (y in -1..1) {
for (x in -1..1) {
drawer.stroke = ColorRGBa.RED.toHSVa()
.shiftHue(0.0 + simplex(500+x+y,seconds)*5.0)
.scaleValue(0.5 + 0.5 * simplex(300+x+y,seconds*4.0).absoluteValue)
.toRGBa()
val r = simplex(400+x+y, seconds) * 150.0 + 150.0
drawer.circle(width / 2.0 + x * 100.0, height / 2.0 + y * 100.0, r)
}
}
}
post(LaserBlur()) {
center = Vector2(simplex(2, seconds*0.1), simplex(100, seconds*0.1))
aberration = simplex(5, seconds) * 0.01
radius = simplex(7, seconds)
}.addTo(gui)
post(GaussianBloom()).addTo(gui)
}
}
extend(gui) {
doubleBind = true
}
extend {
c.draw(drawer)
}
}
}

View File

@@ -0,0 +1,118 @@
package org.openrndr.extra.fx.blur
import org.openrndr.draw.ColorBuffer
import org.openrndr.draw.ColorType
import org.openrndr.draw.Filter
import org.openrndr.draw.filterShaderFromUrl
import org.openrndr.extra.fx.filterFragmentUrl
import org.openrndr.extra.noise.simplex
import org.openrndr.extra.parameters.*
import org.openrndr.math.Vector2
import java.lang.Math.pow
private class LaserBlurPass : Filter(filterShaderFromUrl(filterFragmentUrl("blur/laser-blur.frag"))) {
var radius: Double by parameters
var amp0: Double by parameters
var amp1: Double by parameters
var center: Vector2 by parameters
var vignette: Double by parameters
var vignetteSize: Double by parameters
var aberration: Double by parameters
var linearInput: Boolean by parameters
var linearOutput: Boolean by parameters
init {
radius = 0.0
amp0 = 1.0
amp1 = 1.0
center = Vector2.ZERO
vignette = 0.0
vignetteSize = 1.0
aberration = 0.0
linearInput = false
linearOutput = false
}
}
@Description("Laser blur")
class LaserBlur : Filter() {
@Vector2Parameter("center", order = 0)
var center = Vector2.ZERO
@DoubleParameter("radius", -2.0, 2.0, order = 1)
var radius = -0.18
@DoubleParameter("amp0", 0.0, 1.0, order = 2)
var amp0 = 0.5
@DoubleParameter("amp1", 0.0, 1.0, order = 3)
var amp1 = 0.5
@DoubleParameter("vignette", 0.0, 1.0, order = 4)
var vignette = 0.0
@DoubleParameter("vignette size", 0.0, 1.0, order = 5)
var vignetteSize = 0.0
@DoubleParameter("aberration", -1.0, 1.0, order = 6)
var aberration = 0.006
@DoubleParameter("exp", -1.0, 1.0, order = 7)
var exp = 0.739
@BooleanParameter("linear input", order = 8)
var linearInput = false
@BooleanParameter("linear output", order = 9)
var linearOutput = false
@DoubleParameter("phase", -1.0, 1.0, order = 7)
var phase = 0.0
private val pass = LaserBlurPass()
@IntParameter("passes", 2, 32, order = 4)
var passes = 15
val intermediates = mutableListOf<ColorBuffer>()
override fun apply(source: Array<ColorBuffer>, target: Array<ColorBuffer>) {
pass.center = center
pass.radius = radius
pass.amp0 = amp0
pass.amp1 = amp1
pass.vignette = vignette
pass.vignetteSize = vignetteSize
pass.aberration = aberration
if ((!intermediates.all { it.isEquivalentTo(source[0], ignoreFormat = true, ignoreType = true) })) {
intermediates.forEach {
it.destroy()
}
intermediates.clear()
}
if (intermediates.size == 0) {
intermediates.add(source[0].createEquivalent(type = ColorType.FLOAT16))
intermediates.add(source[0].createEquivalent(type = ColorType.FLOAT16))
}
pass.radius = 1.0 + Math.pow(exp, 0.0) * radius
pass.linearInput = linearInput
pass.linearOutput = true
pass.apply(source[0], intermediates[0])
for (i in 0 until passes - 1) {
pass.linearInput = true
pass.linearOutput = true
pass.radius = 1.0 + Math.pow(exp, i + 1.0) * radius //(1.0 + simplex(0, phase + i)) / 2.0
pass.apply(intermediates[i % 2], intermediates[(i + 1) % 2])
}
pass.radius = 1.0 + Math.pow(exp, (passes) * 1.0) * radius
pass.linearInput = true
pass.linearOutput = linearOutput
pass.apply(intermediates[(passes + 1) % 2], target[0])
}
}

View File

@@ -0,0 +1,50 @@
#version 330 core
out vec4 o_output;
uniform sampler2D tex0;
in vec2 v_texCoord0;
uniform float radius;
uniform float amp0;
uniform float amp1;
uniform vec2 center;
uniform float vignette;
uniform float vignetteSize;
uniform float aberration;
uniform bool linearInput;
uniform bool linearOutput;
void main() {
vec4 i0 = texture(tex0, v_texCoord0);
if (!linearInput) {
i0.rgb = pow(i0.rgb, vec3(2.2));
}
vec2 vt = (v_texCoord0 - vec2(0.5, 0.5) + center) * radius + vec2(0.5, 0.5) - center;
vec2 size = textureSize(tex0, 0);
vec2 l = (v_texCoord0 - vec2(0.5, 0.5) + center) * vec2(1.0, size.y/size.x);
float d = length(l);
if (vt.x >= 0.0 && vt.y >= 0.0 && vt.x <= 1.0 && vt.y <= 1.0) {
vec4 i1r = texture(tex0, (v_texCoord0 - vec2(0.5, 0.5) + center) * (radius*(1.0 + aberration)) + vec2(0.5, 0.5) - center);
vec4 i1g = texture(tex0, (v_texCoord0 - vec2(0.5, 0.5) + center) * (radius*(1.0)) + vec2(0.5, 0.5) - center);
vec4 i1b = texture(tex0, (v_texCoord0 - vec2(0.5, 0.5) + center) * (radius*(1.0 - aberration)) + vec2(0.5, 0.5) - center);
i1r.rgb = i1r.a > 0.0 ? i1r.rgb / i1r.a : vec3(0.0);
i1g.rgb = i1g.a > 0.0 ? i1g.rgb / i1g.a : vec3(0.0);
i1b.rgb = i1b.a > 0.0 ? i1b.rgb / i1b.a : vec3(0.0);
vec4 i1 = vec4(i1r.r, i1g.g, i1b.b, 1.0) * (i1r.a + i1g.a + i1b.a)/3.0;
if (!linearInput) {
i1.rgb = pow(i1.rgb, vec3(2.2));
}
o_output = i0 * amp0 + i1 * amp1;
} else {
o_output = i0 * 0.5;
}
o_output.rgb *= mix(1.0, smoothstep(vignetteSize, 0.0, d), vignette);
if (!linearOutput) {
o_output.rgb = pow(o_output.rgb, vec3(1.0 / 2.2));
}
}