2023-11-24 10:41:53 +01:00
|
|
|
globalvar GAUSSIAN_COEFF;
|
|
|
|
GAUSSIAN_COEFF = {};
|
|
|
|
|
2023-02-14 07:37:13 +01:00
|
|
|
function surface_blur_init() {
|
|
|
|
__blur_hori = surface_create(1, 1);
|
|
|
|
__blur_vert = surface_create(1, 1);
|
|
|
|
}
|
|
|
|
|
2023-11-24 10:41:53 +01:00
|
|
|
function __gaussian_get_kernel(size) {
|
|
|
|
size = max(1, round(size));
|
|
|
|
if(struct_has(GAUSSIAN_COEFF, size)) return GAUSSIAN_COEFF[$ size];
|
|
|
|
|
|
|
|
var gau_array = array_create(size);
|
|
|
|
var we = 0;
|
|
|
|
var b = 0.3 * ((size - 1) * 0.5 - 1) + 0.8;
|
|
|
|
for(var i = 0; i < size; i++) {
|
|
|
|
var _x = i * .5;
|
|
|
|
|
|
|
|
gau_array[i] = (1 / sqrt(2 * pi * b)) * exp( -sqr(_x) / (2 * sqr(b)) );
|
|
|
|
we += i? gau_array[i] * 2 : gau_array[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
for(var i = 0; i < size; i++)
|
|
|
|
gau_array[i] /= we;
|
|
|
|
|
|
|
|
GAUSSIAN_COEFF[$ size] = gau_array;
|
|
|
|
return gau_array;
|
|
|
|
}
|
|
|
|
|
2023-01-17 08:11:55 +01:00
|
|
|
function surface_apply_gaussian(surface, size, bg = false, bg_c = c_white, sampleMode = 0, overColor = noone) {
|
|
|
|
static uni_bor = shader_get_uniform(sh_blur_gaussian, "sampleMode");
|
2022-01-13 05:24:03 +01:00
|
|
|
static uni_dim = shader_get_uniform(sh_blur_gaussian, "dimension");
|
|
|
|
static uni_hor = shader_get_uniform(sh_blur_gaussian, "horizontal");
|
|
|
|
static uni_wei = shader_get_uniform(sh_blur_gaussian, "weight");
|
|
|
|
static uni_sze = shader_get_uniform(sh_blur_gaussian, "size");
|
2023-01-17 08:11:55 +01:00
|
|
|
static uni_ovr = shader_get_uniform(sh_blur_gaussian, "overrideColor");
|
|
|
|
static uni_ovc = shader_get_uniform(sh_blur_gaussian, "overColor");
|
2022-12-27 04:00:50 +01:00
|
|
|
|
2023-03-19 09:17:39 +01:00
|
|
|
var format = surface_get_format(surface)
|
2023-09-08 21:37:36 +02:00
|
|
|
__blur_hori = surface_verify(__blur_hori, surface_get_width_safe(surface), surface_get_height_safe(surface), format);
|
|
|
|
__blur_vert = surface_verify(__blur_vert, surface_get_width_safe(surface), surface_get_height_safe(surface), format);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-11-24 10:41:53 +01:00
|
|
|
size = min(size, 128);
|
|
|
|
var gau_array = __gaussian_get_kernel(size);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-02-14 07:37:13 +01:00
|
|
|
BLEND_OVERRIDE;
|
2023-03-21 03:01:53 +01:00
|
|
|
gpu_set_tex_filter(true);
|
2023-02-14 07:37:13 +01:00
|
|
|
surface_set_target(__blur_hori);
|
2022-01-13 05:24:03 +01:00
|
|
|
draw_clear_alpha(bg_c, bg);
|
|
|
|
|
|
|
|
shader_set(sh_blur_gaussian);
|
2023-09-08 21:37:36 +02:00
|
|
|
shader_set_uniform_f_array_safe(uni_dim, [ surface_get_width_safe(surface), surface_get_height_safe(surface) ]);
|
2023-02-14 07:37:13 +01:00
|
|
|
shader_set_uniform_f_array_safe(uni_wei, gau_array);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-01-17 08:11:55 +01:00
|
|
|
shader_set_uniform_i(uni_bor, sampleMode);
|
2022-01-13 05:24:03 +01:00
|
|
|
shader_set_uniform_i(uni_sze, size);
|
|
|
|
shader_set_uniform_i(uni_hor, 1);
|
|
|
|
|
2023-01-17 08:11:55 +01:00
|
|
|
shader_set_uniform_i(uni_ovr, overColor != noone);
|
2023-02-14 07:37:13 +01:00
|
|
|
shader_set_uniform_f_array_safe(uni_ovc, colToVec4(overColor));
|
2022-12-27 04:00:50 +01:00
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
draw_surface_safe(surface, 0, 0);
|
|
|
|
shader_reset();
|
|
|
|
surface_reset_target();
|
|
|
|
|
2023-02-14 07:37:13 +01:00
|
|
|
surface_set_target(__blur_vert);
|
2022-01-13 05:24:03 +01:00
|
|
|
draw_clear_alpha(bg_c, bg);
|
|
|
|
|
|
|
|
shader_set(sh_blur_gaussian);
|
|
|
|
shader_set_uniform_i(uni_hor, 0);
|
|
|
|
|
2023-02-14 07:37:13 +01:00
|
|
|
draw_surface_safe(__blur_hori, 0, 0);
|
2022-01-13 05:24:03 +01:00
|
|
|
shader_reset();
|
|
|
|
surface_reset_target();
|
2023-03-21 03:01:53 +01:00
|
|
|
gpu_set_tex_filter(false);
|
2023-02-14 07:37:13 +01:00
|
|
|
BLEND_NORMAL;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-02-14 07:37:13 +01:00
|
|
|
return __blur_vert;
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|