Files
2026-01-09 23:21:38 +00:00

151 lines
5.3 KiB
Plaintext
Executable File

// Restrict to 7x7 kernel size for performance reasons
#define MX_MAX_SAMPLE_COUNT 49
// Size of all weights for all levels (including level 1)
#define MX_WEIGHT_ARRAY_SIZE 84
//
// Function to compute the sample size relative to a texture coordinate
//
vector2 mx_compute_sample_size_uv(vector2 uv, float filterSize, float filterOffset)
{
vector derivUVx = Dx(vector(uv.x, uv.y, 0.0)) * 0.5;
vector derivUVy = Dy(vector(uv.x, uv.y, 0.0)) * 0.5;
float derivX = abs(derivUVx[0]) + abs(derivUVy[0]);
float derivY = abs(derivUVx[1]) + abs(derivUVy[1]);
float sampleSizeU = filterSize * derivX + filterOffset;
if (sampleSizeU < 1.0E-05)
sampleSizeU = 1.0E-05;
float sampleSizeV = filterSize * derivY + filterOffset;
if (sampleSizeV < 1.0E-05)
sampleSizeV = 1.0E-05;
return vector2(sampleSizeU, sampleSizeV);
}
// Kernel weights for box filter
void mx_get_box_weights(output float W[MX_MAX_SAMPLE_COUNT], int filterSize)
{
int sampleCount = filterSize*filterSize;
float value = 1.0 / float(sampleCount);
for (int i=0; i<sampleCount; i++)
{
W[i] = value;
}
}
// Kernel weights for Gaussian filter. Sigma is assumed to be 1.
void mx_get_gaussian_weights(output float W[MX_MAX_SAMPLE_COUNT], int filterSize)
{
if (filterSize >= 7)
{
W[0] = 0.000036; W[1] = 0.000363; W[2] = 0.001446; W[3] = 0.002291; W[4] = 0.001446; W[5] = 0.000363; W[6] = 0.000036;
W[7] = 0.000363; W[8] = 0.003676; W[9] = 0.014662; W[10] = 0.023226; W[11] = 0.014662; W[12] = 0.003676; W[13] = 0.000363;
W[14] = 0.001446; W[15] = 0.014662; W[16] = 0.058488; W[17] = 0.092651; W[18] = 0.058488; W[19] = 0.014662; W[20] = 0.001446;
W[21] = 0.002291; W[22] = 0.023226; W[23] = 0.092651; W[24] = 0.146768; W[25] = 0.092651; W[26] = 0.023226; W[27] = 0.002291;
W[28] = 0.001446; W[29] = 0.014662; W[30] = 0.058488; W[31] = 0.092651; W[32] = 0.058488; W[33] = 0.014662; W[34] = 0.001446;
W[35] = 0.000363; W[36] = 0.003676; W[37] = 0.014662; W[38] = 0.023226; W[39] = 0.014662; W[40] = 0.003676; W[41] = 0.000363;
W[42] = 0.000036; W[43] = 0.000363; W[44] = 0.001446; W[45] = 0.002291; W[46] = 0.001446; W[47] = 0.000363; W[48] = 0.000036;
}
else if (filterSize >= 5)
{
W[0] = 0.003765; W[1] = 0.015019; W[2] = 0.023792; W[3] = 0.015019; W[4] = 0.003765;
W[5] = 0.015019; W[6] = 0.059912; W[7] = 0.094907; W[8] = 0.059912; W[9] = 0.015019;
W[10] = 0.023792; W[11] = 0.094907; W[12] = 0.150342; W[13] = 0.094907; W[14] = 0.023792;
W[15] = 0.015019; W[16] = 0.059912; W[17] = 0.094907; W[18] = 0.059912; W[19] = 0.015019;
W[20] = 0.003765; W[21] = 0.015019; W[22] = 0.023792; W[23] = 0.015019; W[24] = 0.003765;
}
else if (filterSize >= 3)
{
W[0] = 0.0625; W[1] = 0.125; W[2] = 0.0625;
W[3] = 0.125; W[4] = 0.25; W[5] = 0.125;
W[6] = 0.0625; W[7] = 0.125; W[8] = 0.0625;
}
else
{
W[0] = 1.0;
}
}
//
// Apply filter for float samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
float mx_convolution_float(float S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
float result = 0.0;
for (int i = 0; i < sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}
//
// Apply filter for vector2 samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vector2 mx_convolution_vector2(vector2 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
vector2 result = vector2(0.0, 0.0);
for (int i=0; i<sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}
//
// Apply filter for vector samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vector mx_convolution_vector(vector S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
vector result = vector(0.0, 0.0, 0.0);
for (int i=0; i<sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}
//
// Apply filter for vector4 samples S, using weights W.
// sampleCount should be a square of a odd number { 1, 3, 5, 7 }
//
vector4 mx_convolution_vector4(vector4 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
vector4 result = vector4(0.0, 0.0, 0.0, 0.0);
for (int i=0; i<sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}
//
// Apply filter for color samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
color mx_convolution_color(color S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
color result = color(0.0);
for (int i=0; i<sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}
//
// Apply filter for color4 samples S, using weights W.
// sampleCount should be a square of a odd number { 1, 3, 5, 7 }
//
color4 mx_convolution_color4(color4 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
color4 result = color4(color(0.0, 0.0, 0.0), 0.0);
for (int i=0; i<sampleCount; i++)
{
result += S[i]*W[i+offset];
}
return result;
}