public static void CalculateGaussian(float dx, float dy, float force, out float[] weightsParameter, out Vector4[] offsetsParameter) {
// Look up how many samples our gaussian blur effect supports.
const int sampleCount = EffectPpBlur.SampleCount;
// Create temporary arrays for computing our filter settings.
var sampleWeights = new float[sampleCount];
var sampleOffsets = new Vector2[sampleCount];
// The first sample always has a zero offset.
sampleWeights[0] = ComputeGaussian(0, force);
sampleOffsets[0] = new Vector2(0);
// Maintain a sum of all the weighting values.
var totalWeights = sampleWeights[0];
// Add pairs of additional sample taps, positioned
// along a line in both directions from the center.
for (var i = 0; i < sampleCount / 2; i++) {
// Store weights for the positive and negative taps.
var weight = ComputeGaussian(i + 1, force);
sampleWeights[i * 2 + 1] = weight;
sampleWeights[i * 2 + 2] = weight;
totalWeights += weight * 2;
// To get the maximum amount of blurring from a limited number of
// pixel shader samples, we take advantage of the bilinear filtering
// hardware inside the texture fetch unit. If we position our texture
// coordinates exactly halfway between two texels, the filtering unit
// will average them for us, giving two samples for the price of one.
// This allows us to step in units of two texels per sample, rather
// than just one at a time. The 1.5 offset kicks things off by
// positioning us nicely in between two texels.
var sampleOffset = i * 2 + 1.5f;
var delta = new Vector2(dx, dy) * sampleOffset;
// Store texture coordinate offsets for the positive and negative taps.
sampleOffsets[i * 2 + 1] = delta;
sampleOffsets[i * 2 + 2] = -delta;
}
// Normalize the list of sample weightings, so they will always sum to one.
for (var i = 0; i < sampleWeights.Length; i++) {
sampleWeights[i] /= totalWeights;
}
// Tell the effect about our new filter settings.
weightsParameter = sampleWeights;
offsetsParameter = sampleOffsets.Select(x => new Vector4(x, 0, 0)).ToArray();
}