Below is a rough translation of a Box blur written in GLSL, it uses the double pass technique. The first reduction filter I wrote in GLSL was a boxBlur, so I figured it might be a good starting point for you. A Gaussian Blur, is basically the same, except that it weighs the values based upon their closeness to the global co-ordinates.
There’s a whole host of things you can do to optimize this code further. It takes 0.6 seconds to process a 300 x 300 picture with a radius of 3, tested on a 2015 12" Retina MacBook 1.1 Ghz. I doubt you’ll match the performance of GLSL, which can do this in less than 0.002 of a second.
[code]Public Function splitBoxBlur(sourceImage as picture, radius as integer) as picture
// — This is a rough translation from a BoxBlur filter written in GLSL by Sam Rowlands.
#pragma backgroundTasks false
#pragma stackOverflowChecking false
#pragma nilObjectChecking false
Dim rvalue as new picture( sourceImage.width, sourceImage.height )
Dim inSurface as RGBSurface = sourceImage.rGBSurface
Dim outSurface as RGBSurface = rvalue.RGBSurface
Dim maxX as integer = sourceImage.width - 1
Dim maxY as integer = sourceImage.height - 1
Dim lYMin, lyMax, lxMin, lxMax as integer
Dim red, green, blue, count as Uint64
Dim c as color
For globalY as integer = 0 to maxY
For globalX as integer = 0 to maxX
red = 0
green = 0
blue = 0
count = 0
lxMin = if( globalX - radius < 0, 0, globalX - radius )
lxMax = if( globalX + radius > maxX, maxX, globalX + radius )
For x as integer = lxMin to lxMax
c = inSurface.pixel( x, globalY )
red = red + c.red
green = green + c.green
blue = blue + c.blue
count = count + 1
Next
outSurface.pixel( globalX, globalY ) = rgb( red / count, green / count, blue / count )
Next
Next
For globalY as integer = 0 to maxY
For globalX as integer = 0 to maxX
red = 0
green = 0
blue = 0
count = 0
lyMin = if( globalY - radius < 0, 0, globalY - radius )
lyMax = if( globalY + radius > maxY, maxY, globalY + radius )
For y as integer = lyMin to lyMax
c = outSurface.pixel( globalx, y )
red = red + c.red
green = green + c.green
blue = blue + c.blue
count = count + 1
Next
outSurface.pixel( globalX, globalY ) = rgb( red / count, green / count, blue / count )
Next
Next
return rvalue
End Function
[/code]