Add FastIntegralImage
This commit is contained in:
77
orx-integral-image/src/main/kotlin/FastIntegralImage.kt
Normal file
77
orx-integral-image/src/main/kotlin/FastIntegralImage.kt
Normal 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])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user