From 641efb38680a2a8a3016685f2f3ee48086a9e1fb Mon Sep 17 00:00:00 2001 From: Tanasart Date: Sun, 9 Jun 2024 15:35:02 +0700 Subject: [PATCH] jpeg --- scripts/node_jpeg/node_jpeg.gml | 45 ++++++++++++------ shaders/sh_jpeg_dct/sh_jpeg_dct.fsh | 56 ++++++++++++++++++++++- shaders/sh_jpeg_recons/sh_jpeg_recons.fsh | 56 ++++++++++++++++++++++- 3 files changed, 139 insertions(+), 18 deletions(-) diff --git a/scripts/node_jpeg/node_jpeg.gml b/scripts/node_jpeg/node_jpeg.gml index 5c300d093..4b83b744b 100644 --- a/scripts/node_jpeg/node_jpeg.gml +++ b/scripts/node_jpeg/node_jpeg.gml @@ -22,11 +22,19 @@ function Node_JPEG(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons __init_mask_modifier(5); // inputs 8, 9 + inputs[| 10] = nodeValue("Transformation", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Cosine", "Zigzag", "Smooth Zigzag", "Step" ]); + + inputs[| 11] = nodeValue("Phase", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) + .setDisplay(VALUE_DISPLAY.rotation); + + inputs[| 12] = nodeValue("Deconstruct Only", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false) + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); input_display_list = [ 1, ["Surface", false], 0, 5, 6, 7, - ["Effects", false], 2, 3, 4, + ["Effects", false], 2, 3, 4, 10, 11, 12, ]; temp_surface = array_create(2); @@ -38,29 +46,38 @@ function Node_JPEG(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons } #endregion static processData = function(_outSurf, _data, _output_index, _array_index) { #region - var _surf = _data[0]; - var _patc = _data[2]; - var _comp = _data[3]; - var _recn = _data[4]; + var _surf = _data[0]; + var _patc = _data[2]; + var _comp = _data[3]; + var _recn = _data[4]; + var _tran = _data[10]; + var _phas = _data[11]; + var _recon = _data[12]; var _dim = surface_get_dimension(_surf); for( var i = 0; i < 2; i++ ) temp_surface[i] = surface_verify(temp_surface[i], _dim[0], _dim[1], surface_rgba16float); - - surface_set_shader(temp_surface[0], sh_jpeg_dct); - shader_set_f("dimension", _dim); - shader_set_i("patch", _patc); - shader_set_f("compression", _comp); - - draw_surface_safe(_surf); - surface_reset_shader(); + + if(!_recon) { + surface_set_shader(temp_surface[0], sh_jpeg_dct); + shader_set_f("dimension", _dim); + shader_set_i("patch", _patc); + shader_set_f("compression", _comp); + shader_set_f("phase", degtorad(_phas)); + shader_set_i("transform", _tran); + + draw_surface_safe(_surf); + surface_reset_shader(); + } surface_set_shader(temp_surface[1], sh_jpeg_recons); shader_set_f("dimension", _dim); shader_set_i("patch", _patc); shader_set_i("reconstruct", _recn); + shader_set_f("phase", degtorad(_phas)); + shader_set_i("transform", _tran); - draw_surface_safe(temp_surface[0]); + draw_surface_safe(_recon? _surf : temp_surface[0]); surface_reset_shader(); surface_set_shader(_outSurf); diff --git a/shaders/sh_jpeg_dct/sh_jpeg_dct.fsh b/shaders/sh_jpeg_dct/sh_jpeg_dct.fsh index 87d32eb27..7ad5ea15a 100644 --- a/shaders/sh_jpeg_dct/sh_jpeg_dct.fsh +++ b/shaders/sh_jpeg_dct/sh_jpeg_dct.fsh @@ -6,9 +6,55 @@ varying vec4 v_vColour; uniform vec2 dimension; uniform int patch; +uniform int transform; uniform float compression; +uniform float phase; -float DCTcoeff(vec2 k, vec2 x) { return cos(PI * k.x * x.x) * cos(PI * k.y * x.y); } +float DCTcoeff(vec2 k, vec2 x) { return cos(PI * k.x * x.x + phase) * cos(PI * k.y * x.y + phase); } +float ZIGcoeff(vec2 k, vec2 x) { + float a, b; + + float fx = fract(k.x * x.x + phase / PI / 2. + .5); + a = fx < 0.5? fx * 2. : (1. - fx) * 2.; + a = a * 2. - 1.; + + float fy = fract(k.y * x.y + phase / PI / 2. + .5); + b = fy < 0.5? fy * 2. : (1. - fy) * 2.; + b = b * 2. - 1.; + + return a * b; +} + +float SMTcoeff(vec2 k, vec2 x) { + float a, b; + + float fx = fract(k.x * x.x + phase / PI / 2. + .5); + a = fx < 0.5? fx * 2. : (1. - fx) * 2.; + a = smoothstep(0., 1., a); + a = a * 2. - 1.; + + float fy = fract(k.y * x.y + phase / PI / 2. + .5); + b = fy < 0.5? fy * 2. : (1. - fy) * 2.; + b = smoothstep(0., 1., b); + b = b * 2. - 1.; + + return a * b; +} + +float STPcoeff(vec2 k, vec2 x) { + float a, b; + float sp = 1. / 2.; + + float _fx = fract(k.x * x.x + phase / PI / 2.); + float fx = _fx >= 0.5 - sp && _fx <= 0.5 + sp? 0. : step(0.5, _fx); + a = a * 2. - 1.; + + float _fy = fract(k.y * x.y + phase / PI / 2.); + float fy = _fy >= 0.5 - sp && _fy <= 0.5 + sp? 0. : step(0.5, _fy); + b = b * 2. - 1.; + + return a * b; +} float round(float val) { return fract(val) > 0.5? ceil(val) : floor(val); } vec4 round(vec4 val) { return vec4(round(val.x), round(val.y), round(val.z), round(val.w)); } @@ -24,7 +70,13 @@ void main() { for(int x = 0; x < patch; ++x) for(int y = 0; y < patch; ++y) { vec4 s = texture2D( gm_BaseTexture, (K + vec2(x, y) + .5) / dimension); - float c = DCTcoeff(k, (vec2(x, y) + .5) / float(patch)); + float c = 0.; + + if(transform == 0) c = DCTcoeff(k, (vec2(x, y) + .5) / float(patch)); + else if(transform == 1) c = ZIGcoeff(k, (vec2(x, y) + .5) / float(patch)); + else if(transform == 2) c = SMTcoeff(k, (vec2(x, y) + .5) / float(patch)); + else if(transform == 3) c = STPcoeff(k, (vec2(x, y) + .5) / float(patch)); + c *= k.x < .5? SQRT2 : 1.; c *= k.y < .5? SQRT2 : 1.; diff --git a/shaders/sh_jpeg_recons/sh_jpeg_recons.fsh b/shaders/sh_jpeg_recons/sh_jpeg_recons.fsh index b355f0e05..78afc5871 100644 --- a/shaders/sh_jpeg_recons/sh_jpeg_recons.fsh +++ b/shaders/sh_jpeg_recons/sh_jpeg_recons.fsh @@ -6,9 +6,55 @@ varying vec4 v_vColour; uniform vec2 dimension; uniform int patch; +uniform int transform; uniform int reconstruct; +uniform float phase; -float DCTcoeff(vec2 k, vec2 x) { return cos(PI * k.x * x.x) * cos(PI * k.y * x.y); } +float DCTcoeff(vec2 k, vec2 x) { return cos(PI * k.x * x.x + phase) * cos(PI * k.y * x.y + phase); } +float ZIGcoeff(vec2 k, vec2 x) { + float a, b; + + float fx = fract(k.x * x.x + phase / PI / 2. + .5); + a = fx < 0.5? fx * 2. : (1. - fx) * 2.; + a = a * 2. - 1.; + + float fy = fract(k.y * x.y + phase / PI / 2. + .5); + b = fy < 0.5? fy * 2. : (1. - fy) * 2.; + b = b * 2. - 1.; + + return a * b; +} + +float SMTcoeff(vec2 k, vec2 x) { + float a, b; + + float fx = fract(k.x * x.x + phase / PI / 2. + .5); + a = fx < 0.5? fx * 2. : (1. - fx) * 2.; + a = smoothstep(0., 1., a); + a = a * 2. - 1.; + + float fy = fract(k.y * x.y + phase / PI / 2. + .5); + b = fy < 0.5? fy * 2. : (1. - fy) * 2.; + b = smoothstep(0., 1., b); + b = b * 2. - 1.; + + return a * b; +} + +float STPcoeff(vec2 k, vec2 x) { + float a, b; + float sp = 1. / 2.; + + float _fx = fract(k.x * x.x + phase / PI / 2.); + float fx = _fx >= 0.5 - sp && _fx <= 0.5 + sp? 0. : step(0.5, _fx); + a = a * 2. - 1.; + + float _fy = fract(k.y * x.y + phase / PI / 2.); + float fy = _fy >= 0.5 - sp && _fy <= 0.5 + sp? 0. : step(0.5, _fy); + b = b * 2. - 1.; + + return a * b; +} void main() { vec2 tx = dimension * v_vTexcoord; @@ -21,7 +67,13 @@ void main() { for(int v = 0; v < reconstruct; ++v) { vec4 s = texture2D( gm_BaseTexture, (K + vec2(u, v) + .5) / dimension); - float c = DCTcoeff(vec2(u, v), (k + .5) / float(patch)); + float c = 0.; + + if(transform == 0) c = DCTcoeff(vec2(u, v), (k + .5) / float(patch)); + else if(transform == 1) c = ZIGcoeff(vec2(u, v), (k + .5) / float(patch)); + else if(transform == 2) c = SMTcoeff(vec2(u, v), (k + .5) / float(patch)); + else if(transform == 3) c = STPcoeff(vec2(u, v), (k + .5) / float(patch)); + c *= u == 0? SQRT2 : 1.; c *= v == 0? SQRT2 : 1.;