1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-02-07 19:09:50 +00:00
Pixelorama/src/Shaders/Effects/ConvolutionMatrix.gdshader
Emmanouil Papadeas cfbe851da5 Add a convolution matrix layer effect
Still WIP, could use some extra parameters such as RGBA channel, and I should also implement it as an image effect.
2024-08-16 04:24:43 +03:00

83 lines
2.1 KiB
Plaintext

shader_type canvas_item;
// author : csblo
// Work made just by consulting :
// https://en.wikipedia.org/wiki/Kernel_(image_processing)
uniform mat3 kernel = mat3(vec3(0, 0, 0), vec3(0, 1, 0), vec3(0, 0, 0));
// Find coordinate of matrix element from index
vec2 kpos(int index, vec2 iResolution)
{
return vec2[9] (
vec2(-1, -1), vec2(0, -1), vec2(1, -1),
vec2(-1, 0), vec2(0, 0), vec2(1, 0),
vec2(-1, 1), vec2(0, 1), vec2(1, 1)
)[index] / iResolution.xy;
}
// Extract region of dimension 3x3 from sampler centered in uv
// sampler : texture sampler
// uv : current coordinates on sampler
// return : an array of mat3, each index corresponding with a color channel
mat3[3] region3x3(sampler2D sampler, vec2 uv, vec2 iResolution)
{
// Create each pixels for region
vec4[9] region;
for (int i = 0; i < 9; i++)
region[i] = texture(sampler, uv + kpos(i, iResolution));
// Create 3x3 region with 3 color channels (red, green, blue)
mat3[3] mRegion;
for (int i = 0; i < 3; i++)
mRegion[i] = mat3(
vec3(region[0][i], region[1][i], region[2][i]),
vec3(region[3][i], region[4][i], region[5][i]),
vec3(region[6][i], region[7][i], region[8][i])
);
return mRegion;
}
// Convolve a texture with kernel
// kernel : kernel used for convolution
// sampler : texture sampler
// uv : current coordinates on sampler
vec3 convolution(sampler2D sampler, vec2 uv, vec2 iResolution)
{
vec3 fragment;
// Extract a 3x3 region centered in uv
mat3[3] region = region3x3(sampler, uv, iResolution);
// for each color channel of region
for (int i = 0; i < 3; i++)
{
// get region channel
mat3 rc = region[i];
// component wise multiplication of kernel by region channel
mat3 c = matrixCompMult(kernel, rc);
// add each component of matrix
float r = c[0][0] + c[1][0] + c[2][0]
+ c[0][1] + c[1][1] + c[2][1]
+ c[0][2] + c[1][2] + c[2][2];
// for fragment at channel i, set result
fragment[i] = r;
}
return fragment;
}
void fragment()
{
// Convolve kernel with texture
vec3 col = convolution(TEXTURE, UV, 1.0 / TEXTURE_PIXEL_SIZE);
// Output to screen
COLOR.rgb = col;
}