Skip to content

Instantly share code, notes, and snippets.

@zz85
Created April 12, 2014 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zz85/10542662 to your computer and use it in GitHub Desktop.
Save zz85/10542662 to your computer and use it in GitHub Desktop.
Coefficients Generation for Optimized Gaussian Blurs using Linear Sampling
/*
* @author zz85 / https://github.com/zz85
*
* Related Readings
*
* http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
* http://www.sunsetlakesoftware.com/2013/10/21/optimizing-gaussian-blurs-mobile-gpu
* http://xissburg.com/faster-gaussian-blur-in-glsl/
* https://github.com/manuelbua/blur-ninja
*
*
* I'm writing this in the process of exploring optimized gaussian blurs,
* but how well it really works in the real world I've yet to figure out.
* For example, using varying to prevent dependent texture reads in the fragment
* shader might be a thing of the past.
* http://stackoverflow.com/questions/1054096/what-is-a-dependent-texture-read
*
*/
calc(13);
function calc( level ) {
if ( level % 2 != 1 ) {
console.log( 'odd number taps only ');
return;
}
var edgesToRemove = 2;
var binom = binomial( level );
console.log('Initial gaussian distribution', binom);
var total = 0;
for (var i = 0; i < binom.length; i++) {
total += binom[ i ];
}
var weights = [];
var offsets = [];
var off = binom.length / 2 + 0.5
for (var i = off - 1; i >= 0; i--) {
weights.push( binom[i] / total );
offsets.push( Math.abs(i + 1 - off));
}
console.log('discrete weights', weights);
console.log('discrete offsets', offsets);
// Remove edges with too little weight.
var weight = 1;
while (edgesToRemove--) {
weight -= weights.pop() * 2;
offsets.pop();
}
for (i = 0; i < weights.length; i++) {
weight[ i ] /= weight;
}
// Calculate linear sampling weights
var linear_weights = [ weights[0] ];
var linear_offsets = [ offsets[0] ];
for (var t1 = 1; t1 < weights.length; t1+=2) {
var t2 = t1 + 1;
linear_weights.push(weights[t1] + weights[t2]);
linear_offsets.push( (offsets[t1] * weights[t1] + offsets[t2] * weights[t2]) / linear_weights[linear_weights.length-1]);
}
console.log('linear weights', linear_weights);
console.log('linear offsets', linear_offsets);
}
// Returns binomial sequence at level n.
// 1 - 1
// 2 - 1, 1
// 3 - 1, 2, 1
// 4 - 1, 3, 3, 1
function binomial( level ) {
var previous = [1];
for (var i = 1; i < level; i++) {
var current = [ 1 ];
for (var j = 0; j < previous.length-1; j++) {
current.push( previous[j] + previous[j + 1] );
}
current.push( 1 );
previous = current;
}
return previous;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment