Files
orx/orx-fx/src/main/kotlin/blur/Bloom.kt
2020-02-02 11:13:38 +01:00

85 lines
2.7 KiB
Kotlin

package org.openrndr.extra.fx.blur
import org.openrndr.draw.*
import org.openrndr.extra.fx.blend.Add
import org.openrndr.extra.fx.filterFragmentCode
import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.extra.parameters.IntParameter
@Description("Bloom")
class Bloom(blur: Filter = ApproximateGaussianBlur()) : Filter(Shader.createFromCode(filterVertexCode, filterFragmentCode("blur/bloom.frag"))) {
/**
* the blur filter to use for the bloom, default is Approximate Gaussian Blur
*/
var blur: Filter = blur
/**
* number of downsampled textures to use, default value is 2
*/
@IntParameter("blur iterations", 1, 8)
var downsamples: Int = 2
/**
* rate of downsampling, f.ex: 4 -> 4x, 8x, 16x.., default value is 2
*/
@IntParameter("downsamping rate", 1, 4)
var downsampleRate: Int = 2
/**
* blending amount between original image and blurred, default value is 0.5
*/
@DoubleParameter("blend factor", 0.0, 1.0)
var blendFactor: Double by parameters
/**
* brightness of the resulting image, default value is 0.5
*/
@DoubleParameter("brightness", 0.0, 1.0)
var brightness: Double by parameters
init {
blendFactor = 0.5
brightness = 0.5
}
private val samplers: MutableList<Pair<ColorBuffer, ColorBuffer>> = mutableListOf()
private var lastDownsampleRate = 0
private val blendAdd = Add()
override fun apply(source: Array<ColorBuffer>, target: Array<ColorBuffer>) {
val src = source[0]
val dest = target[0]
if (samplers.isEmpty() || samplers.size != downsamples || lastDownsampleRate != downsampleRate) {
samplers.clear()
lastDownsampleRate = downsampleRate
for (downsample in 0 until downsamples) {
val div = 1 shl downsample
val bufferA = colorBuffer(dest.width/div, dest.height/div, 1.0, target[0].format, ColorType.FLOAT16)
val bufferB = colorBuffer(dest.width/div, dest.height/div, 1.0, target[0].format, ColorType.FLOAT16)
samplers.add(Pair(bufferA, bufferB))
}
}
for ((bufferA, _) in samplers) {
blur.apply(src, bufferA)
}
for ((index, buffers) in samplers.asReversed().withIndex()) {
val (bufferCurrA) = buffers
if (index + 1 <= samplers.lastIndex) {
val (bufferNextA, bufferNextB) = samplers.asReversed()[index + 1]
blur.apply(bufferCurrA, bufferNextB)
blendAdd.apply(arrayOf(bufferNextA, bufferNextB), bufferNextA)
} else {
super.apply(arrayOf(src, bufferCurrA), target)
}
}
}
}