mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-25 06:04:57 +00:00
151 lines
5.3 KiB
Plaintext
Executable File
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;
|
|
}
|