From 6c2692fb634783e6cdd39c0fb8c00973a78650ee Mon Sep 17 00:00:00 2001 From: Ricardo Matias Date: Tue, 7 Jan 2020 13:29:40 +0100 Subject: [PATCH] Add Bloom effect --- orx-fx/src/main/kotlin/color/Bloom.kt | 79 +++++++++++++++++++ .../openrndr/extra/fx/gl3/color/bloom.frag | 20 +++++ 2 files changed, 99 insertions(+) create mode 100644 orx-fx/src/main/kotlin/color/Bloom.kt create mode 100644 orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/color/bloom.frag diff --git a/orx-fx/src/main/kotlin/color/Bloom.kt b/orx-fx/src/main/kotlin/color/Bloom.kt new file mode 100644 index 00000000..fc5e89ed --- /dev/null +++ b/orx-fx/src/main/kotlin/color/Bloom.kt @@ -0,0 +1,79 @@ +package org.openrndr.extra.fx.color + +import org.openrndr.draw.* +import org.openrndr.extra.fx.blend.Add +import org.openrndr.extra.fx.blur.ApproximateGaussianBlur +import org.openrndr.extra.fx.filterFragmentCode + + +class Bloom(blur: Filter = ApproximateGaussianBlur()) : Filter(Shader.createFromCode(filterVertexCode, filterFragmentCode("color/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 + */ + var downsamples: Int = 2 + + /** + * rate of downsampling, f.ex: 4 -> 4x, 8x, 16x.., default value is 2 + */ + var downsampleRate: Int = 2 + + /** + * blending amount between original image and blurred, default value is 0.5 + */ + var blendFactor: Double by parameters + + /** + * brightness of the resulting image, default value is 0.5 + */ + var brightness: Double by parameters + + init { + blendFactor = 0.5 + brightness = 0.5 + } + + private val samplers: MutableList> = mutableListOf() + private var lastDownsampleRate = 0 + + private val blendAdd = Add() + + override fun apply(source: Array, target: Array) { + 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 * 2 step 2) { + val bufferA = colorBuffer(dest.width, dest.height, 1.0 / (downsample + downsampleRate), target[0].format, ColorType.FLOAT16) + val bufferB = colorBuffer(dest.width, dest.height, 1.0 / (downsample + downsampleRate), 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) + } + } + } +} \ No newline at end of file diff --git a/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/color/bloom.frag b/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/color/bloom.frag new file mode 100644 index 00000000..720523d9 --- /dev/null +++ b/orx-fx/src/main/resources/org/openrndr/extra/fx/gl3/color/bloom.frag @@ -0,0 +1,20 @@ +#version 330 + +in vec2 v_texCoord0; +out vec4 o_color; + +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform float blendFactor; +uniform float brightness; + +void main() { + vec3 original = texture(tex0, v_texCoord0).rgb; + vec3 bloom = texture(tex1, v_texCoord0).rgb; + + vec3 hdrColor = mix(original, bloom, blendFactor); + + vec3 result = vec3(1.0) - exp(-hdrColor * brightness); + + o_color = vec4(result, 1.0); +}