Add FastIntegralImage

This commit is contained in:
Edwin Jakobs
2019-01-17 19:39:31 +01:00
parent a05e1e8b6d
commit 47d2c94df5
2 changed files with 103 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
package org.openrndr.extra.integralimage
import org.openrndr.draw.*
import org.openrndr.filter.blend.passthrough
import org.openrndr.math.Vector2
import org.openrndr.resourceUrl
class FastIntegralImageFilter : Filter(filterShaderFromUrl(resourceUrl(
"/shaders/gl3/integral-image.frag"
))) {
var passIndex: Int by parameters
var passDirection: Vector2 by parameters
var sampleCount: Int by parameters
var sampleCountBase: Int by parameters
}
class FastIntegralImage : Filter(filterShaderFromUrl(resourceUrl(
"/shaders/gl3/integral-image.frag"
))) {
var intermediate: ColorBuffer? = null
val filter = FastIntegralImageFilter()
private fun sampleCounts(size:Int, sampleCountBase:Int) : List<Int> {
var remainder = size
val sampleCounts = mutableListOf<Int>()
while (remainder > 0) {
sampleCounts += if (remainder >= sampleCountBase) {
sampleCountBase
} else {
remainder
}
remainder /= sampleCountBase
}
return sampleCounts
}
override fun apply(source: Array<ColorBuffer>, target: Array<ColorBuffer>) {
val sampleCountBase = 16
val xSampleCounts = sampleCounts(source[0].width, sampleCountBase)
val ySampleCounts = sampleCounts(source[0].height, sampleCountBase)
val li = intermediate
if (li == null || (li.width != source[0].width || li.height != source[0].height)) {
intermediate?.destroy()
intermediate = colorBuffer(source[0].width, source[0].height, 1.0, ColorFormat.RGBa, ColorType.FLOAT32)
}
val targets = arrayOf(target, arrayOf(intermediate!!))
var targetIndex = 0
filter.sampleCountBase = sampleCountBase
filter.passDirection = Vector2.UNIT_X
for (pass in 0 until xSampleCounts.size) {
filter.sampleCount = xSampleCounts[pass]
filter.passIndex = pass
filter.apply( if (pass == 0) source else targets[targetIndex%2], targets[(targetIndex+1)%2])
targetIndex++
}
filter.passDirection = Vector2.UNIT_Y
for (pass in 0 until ySampleCounts.size) {
filter.sampleCount = ySampleCounts[pass]
filter.passIndex = pass
filter.apply( targets[targetIndex%2], targets[(targetIndex+1)%2])
targetIndex++
}
if (targetIndex%2 == 1) {
passthrough.apply(targets[1], targets[0])
}
}
}

View File

@@ -0,0 +1,26 @@
#version 330 core
uniform sampler2D tex0;
in vec2 v_texCoord0;
out vec4 o_color;
uniform int passIndex;
uniform int sampleCount;
uniform int sampleCountBase;
uniform vec2 passDirection;
void main() {
vec2 passOffset = vec2(pow(sampleCountBase, passIndex)) * (1.0/textureSize(tex0, 0)) * passDirection;
vec2 uv0 = v_texCoord0;
vec4 result = vec4(0.0);
for (int i = 0; i < sampleCount; ++i) {
vec2 readUV = v_texCoord0 - vec2(i *passOffset);
float factor = step(0.0, readUV.x) * step(0.0, readUV.y);
result += factor * texture(tex0, readUV);
}
o_color = result;
}