mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-25 06:26:42 +01:00
equation
This commit is contained in:
parent
920c6dc1a7
commit
d46795a40b
13 changed files with 1427 additions and 948 deletions
|
@ -544,6 +544,7 @@
|
|||
{"name":"sh_skew","order":6,"path":"shaders/sh_skew/sh_skew.yy",},
|
||||
{"name":"libxprocess","order":4,"path":"extensions/libxprocess/libxprocess.yy",},
|
||||
{"name":"fd_rectangle_get_pressure_height","order":16,"path":"scripts/fd_rectangle_get_pressure_height/fd_rectangle_get_pressure_height.yy",},
|
||||
{"name":"hyperbolic_function","order":16,"path":"scripts/hyperbolic_function/hyperbolic_function.yy",},
|
||||
{"name":"node_VFX_effect_destroy","order":12,"path":"scripts/node_VFX_effect_destroy/node_VFX_effect_destroy.yy",},
|
||||
{"name":"node_cache","order":9,"path":"scripts/node_cache/node_cache.yy",},
|
||||
{"name":"sh_bw","order":5,"path":"shaders/sh_bw/sh_bw.yy",},
|
||||
|
|
|
@ -1085,6 +1085,7 @@
|
|||
{"id":{"name":"sh_skew","path":"shaders/sh_skew/sh_skew.yy",},},
|
||||
{"id":{"name":"libxprocess","path":"extensions/libxprocess/libxprocess.yy",},},
|
||||
{"id":{"name":"fd_rectangle_get_pressure_height","path":"scripts/fd_rectangle_get_pressure_height/fd_rectangle_get_pressure_height.yy",},},
|
||||
{"id":{"name":"hyperbolic_function","path":"scripts/hyperbolic_function/hyperbolic_function.yy",},},
|
||||
{"id":{"name":"s_node_fluidSim_repulse","path":"sprites/s_node_fluidSim_repulse/s_node_fluidSim_repulse.yy",},},
|
||||
{"id":{"name":"node_VFX_effect_destroy","path":"scripts/node_VFX_effect_destroy/node_VFX_effect_destroy.yy",},},
|
||||
{"id":{"name":"node_cache","path":"scripts/node_cache/node_cache.yy",},},
|
||||
|
|
File diff suppressed because it is too large
Load diff
3
scripts/hyperbolic_function/hyperbolic_function.gml
Normal file
3
scripts/hyperbolic_function/hyperbolic_function.gml
Normal file
|
@ -0,0 +1,3 @@
|
|||
function sinh(x) { return (exp(x) - exp(-x)) / 2; }
|
||||
function cosh(x) { return (exp(x) + exp(-x)) / 2; }
|
||||
function tanh(x) { return (exp(2 * x) - 1) / (exp(2 * x) + 1); }
|
11
scripts/hyperbolic_function/hyperbolic_function.yy
Normal file
11
scripts/hyperbolic_function/hyperbolic_function.yy
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"resourceType": "GMScript",
|
||||
"resourceVersion": "1.0",
|
||||
"name": "hyperbolic_function",
|
||||
"isCompatibility": false,
|
||||
"isDnD": false,
|
||||
"parent": {
|
||||
"name": "value",
|
||||
"path": "folders/functions/value.yy",
|
||||
},
|
||||
}
|
|
@ -2,17 +2,6 @@ function Node_Camera(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
name = "Camera";
|
||||
preview_alpha = 0.5;
|
||||
|
||||
shader = sh_camera;
|
||||
uni_backg = shader_get_sampler_index(shader, "backg");
|
||||
uni_scene = shader_get_sampler_index(shader, "scene");
|
||||
uni_dim_scn = shader_get_uniform(shader, "scnDimension");
|
||||
uni_dim_cam = shader_get_uniform(shader, "camDimension");
|
||||
uni_pos = shader_get_uniform(shader, "position");
|
||||
uni_zom = shader_get_uniform(shader, "zoom");
|
||||
uni_sam_mod = shader_get_uniform(shader, "sampleMode");
|
||||
uni_blur = shader_get_uniform(shader, "blur");
|
||||
uni_fix_bg = shader_get_uniform(shader, "fixBG");
|
||||
|
||||
inputs[| 0] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0);
|
||||
inputs[| 1] = nodeValue("Focus area", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0, 16, 16, AREA_SHAPE.rectangle ])
|
||||
.setDisplay(VALUE_DISPLAY.area, function() { return getDimension(0); });
|
||||
|
@ -21,15 +10,23 @@ function Node_Camera(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
.setDisplay(VALUE_DISPLAY.slider, [ 0.01, 4, 0.01 ]);
|
||||
|
||||
inputs[| 3] = nodeValue("Oversample mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, "How to deal with pixel outside the surface.\n - Empty: Use empty pixel\n - Clamp: Repeat edge pixel\n - Repeat: Repeat texture.")
|
||||
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Repeat" ]);
|
||||
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Repeat", "Repeat X", "Repeat Y" ]);
|
||||
|
||||
inputs[| 4] = nodeValue("Fix background", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false);
|
||||
|
||||
inputs[| 5] = nodeValue("Depth of Field", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false);
|
||||
|
||||
inputs[| 6] = nodeValue("Focal distance", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0);
|
||||
|
||||
inputs[| 7] = nodeValue("Defocus", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1);
|
||||
|
||||
inputs[| 8] = nodeValue("Focal range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0);
|
||||
|
||||
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
|
||||
|
||||
input_display_list = [
|
||||
["Background", true], 0, 4, 3,
|
||||
["Camera", false], 1, 2,
|
||||
["Camera", false], 1, 2, 5, 6, 8, 7,
|
||||
["Elements", true],
|
||||
];
|
||||
|
||||
|
@ -52,7 +49,7 @@ function Node_Camera(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
.setUnitRef(function(index) { return getDimension(index); });
|
||||
|
||||
inputs[| index + 2] = nodeValue($"Oversample {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
|
||||
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Repeat" ]);
|
||||
.setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Repeat", "Repeat X", "Repeat Y" ]);
|
||||
|
||||
array_append(input_display_list, [ index + 0, index + 1, index + 2 ]);
|
||||
}
|
||||
|
@ -128,6 +125,12 @@ function Node_Camera(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
var _zoom = _data[2];
|
||||
var _samp = _data[3];
|
||||
var _fix = _data[4];
|
||||
|
||||
var _dof = _data[5];
|
||||
var _dof_dist = _data[6];
|
||||
var _dof_stop = _data[7];
|
||||
var _dof_rang = _data[8];
|
||||
|
||||
var cDep = attrDepth();
|
||||
|
||||
var _cam_x = round(_area[0]);
|
||||
|
@ -147,58 +150,65 @@ function Node_Camera(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
|
||||
surface_set_target(temp_surface[0]);
|
||||
DRAW_CLEAR
|
||||
BLEND_OVERRIDE;
|
||||
if(amo <= 0) {
|
||||
if(_fix) {
|
||||
if(_samp) draw_surface_tiled_safe(_data[0], 0, 0);
|
||||
else draw_surface_safe(_data[0], 0, 0);
|
||||
} else {
|
||||
var sx = _cam_x / _zoom - _cam_w;
|
||||
var sy = _cam_y / _zoom - _cam_h;
|
||||
if(_samp) draw_surface_tiled_ext_safe(_data[0], -sx, -sy, 1 / _zoom, 1 / _zoom, c_white, 1);
|
||||
else draw_surface_ext_safe(_data[0], -sx, -sy, 1 / _zoom, 1 / _zoom, 0, c_white, 1);
|
||||
}
|
||||
} else {
|
||||
var sx = _cam_x / _zoom - _cam_w;
|
||||
var sy = _cam_y / _zoom - _cam_h;
|
||||
|
||||
if(_fix) draw_surface_safe(_data[0], 0, 0);
|
||||
else draw_surface_tiled_ext_safe(_data[0], sx, sy, 1 / _zoom, 1 / _zoom, c_white, 1);
|
||||
}
|
||||
BLEND_NORMAL;
|
||||
surface_reset_target();
|
||||
|
||||
surface_set_target(temp_surface[1]);
|
||||
DRAW_CLEAR
|
||||
surface_reset_target();
|
||||
|
||||
shader_set(shader);
|
||||
shader_set_uniform_f(uni_dim_cam, _surf_w, _surf_h);
|
||||
shader_set_uniform_f(uni_zom, _zoom);
|
||||
shader_set(sh_camera);
|
||||
shader_set_f("camDimension", _surf_w, _surf_h);
|
||||
shader_set_f("zoom", _zoom);
|
||||
|
||||
for( var i = 0; i < amo; i++ ) {
|
||||
var _surface, sx, sy, sz, _samp;
|
||||
var px, py;
|
||||
var _scnW, _scnH;
|
||||
|
||||
for( var i = -1; i < amo; i++ ) {
|
||||
ppInd = !ppInd;
|
||||
|
||||
surface_set_target(temp_surface[ppInd]);
|
||||
var ind = input_fix_len + i * data_length;
|
||||
if(i == -1) {
|
||||
_surface = _data[0];
|
||||
sx = _fix? 0 : _cam_x;
|
||||
sy = _fix? 0 : _cam_y;
|
||||
sz = 0;
|
||||
_samp = _data[3];
|
||||
|
||||
px = sx;
|
||||
py = sy;
|
||||
} else {
|
||||
var ind = input_fix_len + i * data_length;
|
||||
|
||||
var _surface = _data[ind];
|
||||
var sz = _data[ind + 1][2];
|
||||
var sx = _data[ind + 1][0] * sz * _cam_x;
|
||||
var sy = _data[ind + 1][1] * sz * _cam_y;
|
||||
var _samp = _data[ind + 2];
|
||||
_surface = _data[ind];
|
||||
sz = _data[ind + 1][2];
|
||||
sx = _data[ind + 1][0] * sz * _cam_x;
|
||||
sy = _data[ind + 1][1] * sz * _cam_y;
|
||||
_samp = _data[ind + 2];
|
||||
|
||||
px = _cam_x + sx;
|
||||
py = _cam_y + sy;
|
||||
}
|
||||
|
||||
var _scnW = surface_get_width(_surface);
|
||||
var _scnH = surface_get_height(_surface);
|
||||
_scnW = surface_get_width(_surface);
|
||||
_scnH = surface_get_height(_surface);
|
||||
|
||||
shader_set_uniform_i(uni_sam_mod, _samp);
|
||||
shader_set_uniform_f(uni_dim_scn, _scnW, _scnH);
|
||||
shader_set_uniform_f(uni_blur, sz);
|
||||
shader_set_uniform_f(uni_pos, (_cam_x + sx) / _scnW, (_cam_y + sy) / _scnH);
|
||||
shader_set_uniform_i(uni_fix_bg, !i && _fix);
|
||||
px /= _scnW;
|
||||
py /= _scnH;
|
||||
|
||||
shader_set_i("bg", i == -1? 1 : 0);
|
||||
shader_set_i("sampleMode", _samp);
|
||||
shader_set_f("scnDimension", _scnW, _scnH);
|
||||
shader_set_f("position", px, py);
|
||||
if(_dof) {
|
||||
var _x = max(abs(sz - _dof_dist) - _dof_rang, 0);
|
||||
_x = _x * tanh(_x / 10);
|
||||
shader_set_f("bokehStrength", _x * _dof_stop);
|
||||
} else shader_set_f("bokehStrength", 0);
|
||||
|
||||
shader_set_surface("backg", temp_surface[!ppInd]); //prev surface
|
||||
shader_set_surface("scene", _surface); //surface to draw
|
||||
|
||||
texture_set_stage(uni_backg, surface_get_texture(temp_surface[!ppInd])); //prev surface
|
||||
texture_set_stage(uni_scene, surface_get_texture(_surface)); //surface to draw
|
||||
draw_sprite_ext(s_fx_pixel, 0, 0, 0, _surf_w, _surf_h, 0, c_white, 1);
|
||||
surface_reset_target();
|
||||
}
|
||||
|
|
|
@ -719,6 +719,7 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor {
|
|||
}
|
||||
|
||||
function nodeGetData(str) {
|
||||
str = string_trim(str);
|
||||
var strs = string_splice(str, ".");
|
||||
|
||||
if(array_length(strs) == 0) return 0;
|
||||
|
@ -726,7 +727,7 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor {
|
|||
if(array_length(strs) == 1) {
|
||||
var splt = string_splice(strs[0], "[");
|
||||
var inp = PROJECT.globalNode.getInput(strs[0]);
|
||||
_val = inp == noone? 0 : inp.getValueRecursive()[0];
|
||||
return inp == noone? 0 : inp.getValueRecursive()[0];
|
||||
} else if(string_lower(strs[0]) == "project") {
|
||||
switch(string_lower(strs[1])) {
|
||||
case "frame" : return PROJECT.animator.current_frame;
|
||||
|
@ -760,7 +761,7 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor {
|
|||
return _junc.getValue();
|
||||
}
|
||||
|
||||
return _val;
|
||||
return 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -1109,8 +1109,10 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
|
|||
} else if(value_from != self)
|
||||
val = value_from.getValueRecursive(_time);
|
||||
|
||||
if(expUse && is_struct(expTree) && expTree.validate())
|
||||
if(expUse && is_struct(expTree) && expTree.validate()) {
|
||||
//print("========== Expression eval ==========")
|
||||
val[0] = expTree.eval({ value: val[0] });
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ function perlin1D(seed, scale = 1, octave = 1, startRange = 0, endRange = 1) {
|
|||
var val = 0;
|
||||
|
||||
repeat(octave) {
|
||||
val = sin(seed * scale) * amp;
|
||||
val = random1D(seed * scale) * amp;
|
||||
scale *= 2;
|
||||
amp /= 2;
|
||||
}
|
||||
|
@ -59,7 +59,22 @@ function perlin1D(seed, scale = 1, octave = 1, startRange = 0, endRange = 1) {
|
|||
return lerp(startRange, endRange, val);
|
||||
}
|
||||
|
||||
function getWiggle(_min, _max, _freq, _time, seed_shift = 0, startTime = noone, endTime = noone) {
|
||||
function wiggle(_min = 0, _max = 1, _freq = 1, _time = 0, _seed = 0, _octave = 1) {
|
||||
_freq = max(1, _freq);
|
||||
|
||||
var sdMin = floor(_time / _freq) * _freq;
|
||||
var sdMax = sdMin + _freq;
|
||||
|
||||
var _x0 = perlin1D(PROJECT.seed + _seed + sdMin, 1, _octave);
|
||||
var _x1 = perlin1D(PROJECT.seed + _seed + sdMax, 1, _octave);
|
||||
|
||||
var t = (_time - sdMin) / (sdMax - sdMin);
|
||||
t = -(cos(pi * t) - 1) / 2;
|
||||
var _lrp = lerp(_x0, _x1, t);
|
||||
return lerp(_min, _max, _lrp);
|
||||
}
|
||||
|
||||
function getWiggle(_min = 0, _max = 1, _freq = 1, _time = 0, _seed = 0, startTime = noone, endTime = noone) {
|
||||
_freq = max(1, _freq);
|
||||
|
||||
var sdMin = floor(_time / _freq) * _freq;
|
||||
|
@ -67,8 +82,8 @@ function getWiggle(_min, _max, _freq, _time, seed_shift = 0, startTime = noone,
|
|||
if(endTime) //Clip at ending
|
||||
sdMax = min(endTime, sdMax);
|
||||
|
||||
var _x0 = (startTime != noone && sdMin <= startTime)? 0.5 : random1D(PROJECT.seed + seed_shift + sdMin);
|
||||
var _x1 = (endTime != noone && sdMax >= endTime)? 0.5 : random1D(PROJECT.seed + seed_shift + sdMax);
|
||||
var _x0 = (startTime != noone && sdMin <= startTime)? 0.5 : random1D(PROJECT.seed + _seed + sdMin);
|
||||
var _x1 = (endTime != noone && sdMax >= endTime)? 0.5 : random1D(PROJECT.seed + _seed + sdMax);
|
||||
|
||||
var t = (_time - sdMin) / (sdMax - sdMin);
|
||||
t = -(cos(pi * t) - 1) / 2;
|
||||
|
|
|
@ -3,10 +3,12 @@ function string_decimal(str) {
|
|||
if(neg) str = string_copy(str, 2, string_length(str) - 1);
|
||||
|
||||
var dec = string_pos(".", str);
|
||||
if(dec == 0) return (neg? "-" : "") + string_digits(str);
|
||||
|
||||
var pre = string_copy(str, 1, dec - 1);
|
||||
var pos = string_copy(str, dec + 1, string_length(str) - dec);
|
||||
|
||||
return (neg? "-" : "") + (dec? string_digits(pre) + "." + string_digits(pos) : string_digits(str));
|
||||
return (neg? "-" : "") + string_digits(pre) + "." + string_digits(pos);
|
||||
}
|
||||
|
||||
function toNumber(str) {
|
||||
|
@ -30,5 +32,6 @@ function toNumber(str) {
|
|||
|
||||
function isNumber(str) {
|
||||
if(is_real(str)) return true;
|
||||
str = string_trim(str);
|
||||
return str == string_decimal(str);
|
||||
}
|
|
@ -24,13 +24,16 @@
|
|||
|
||||
global.EQUATION_PRES[? "@"] = 5; //array accerssor symbol
|
||||
|
||||
global.EQUATION_PRES[? "sin"] = 5;
|
||||
global.EQUATION_PRES[? "cos"] = 5;
|
||||
global.EQUATION_PRES[? "tan"] = 5;
|
||||
global.EQUATION_PRES[? "abs"] = 5;
|
||||
global.EQUATION_PRES[? "round"] = 5;
|
||||
global.EQUATION_PRES[? "ceil"] = 5;
|
||||
global.EQUATION_PRES[? "floor"] = 5;
|
||||
global.FUNCTIONS = ds_map_create();
|
||||
global.FUNCTIONS[? "sin"] = [ 1, function(val) { return sin(val[0]); } ];
|
||||
global.FUNCTIONS[? "cos"] = [ 1, function(val) { return cos(val[0]); } ];
|
||||
global.FUNCTIONS[? "tan"] = [ 1, function(val) { return tan(val[0]); } ];
|
||||
global.FUNCTIONS[? "abs"] = [ 1, function(val) { return abs(val[0]); } ];
|
||||
global.FUNCTIONS[? "round"] = [ 1, function(val) { return round(val[0]); } ];
|
||||
global.FUNCTIONS[? "ceil"] = [ 1, function(val) { return ceil(val[0]); } ];
|
||||
global.FUNCTIONS[? "floor"] = [ 1, function(val) { return floor(val[0]); } ];
|
||||
|
||||
global.FUNCTIONS[? "wiggle"] = [ 2, function(val) { return wiggle(0, 1, val[1], val[0]); } ];
|
||||
#endregion
|
||||
|
||||
function functionStringClean(fx) {
|
||||
|
@ -62,7 +65,6 @@ function functionStringClean(fx) {
|
|||
self.symbol = symbol;
|
||||
self.l = l;
|
||||
self.r = r;
|
||||
isFunc = false;
|
||||
|
||||
static _string = function(str) {
|
||||
return string_char_at(str, 1) == "\"" &&
|
||||
|
@ -73,15 +75,15 @@ function functionStringClean(fx) {
|
|||
return _string(str)? string_copy(str, 2, string_length(str) - 2) : string(str);
|
||||
}
|
||||
|
||||
static getVal = function(val, params = {}, getStr = false) {
|
||||
if(is_struct(val)) return val.eval();
|
||||
static getVal = function(val, params = {}, getRaw = false) {
|
||||
if(is_struct(val)) return val.eval(params);
|
||||
if(is_real(val)) return val;
|
||||
if(is_string(val)) val = string_trim(val);
|
||||
|
||||
if(struct_has(params, val))
|
||||
return struct_try_get(params, val);
|
||||
|
||||
if(getStr)
|
||||
return val;
|
||||
if(getRaw) return val;
|
||||
|
||||
if(_string(string_trim(val)))
|
||||
return string_trim(val);
|
||||
|
@ -115,8 +117,17 @@ function functionStringClean(fx) {
|
|||
}
|
||||
|
||||
static validate = function() {
|
||||
if(ds_map_exists(global.FUNCTIONS, symbol)) {
|
||||
if(!is_array(l)) return false;
|
||||
for( var i = 0; i < array_length(l); i++ )
|
||||
if(!_validate(l[i])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch(symbol) {
|
||||
case "@": return _validate(l);
|
||||
case "【": return true;
|
||||
case "": return true;
|
||||
}
|
||||
|
||||
return _validate(l) && _validate(r);
|
||||
|
@ -145,15 +156,61 @@ function functionStringClean(fx) {
|
|||
}
|
||||
|
||||
static eval = function(params = {}) {
|
||||
var v1 = getVal(l, params);
|
||||
var v2 = getVal(r, params, symbol == "@");
|
||||
if(ds_map_exists(global.FUNCTIONS, symbol)) {
|
||||
if(!is_array(l)) return 0;
|
||||
|
||||
var _fn = global.FUNCTIONS[? symbol];
|
||||
var _ev = _fn[1];
|
||||
var _l = array_create(array_length(l));
|
||||
|
||||
for( var i = 0; i < array_length(l); i++ )
|
||||
_l[i] = getVal(l[i], params);
|
||||
|
||||
var res = _ev(_l);
|
||||
//print($"Function {symbol}{_l} = {res}");
|
||||
//print("====================");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//print($"|{v1}|{symbol}|{v2}|");
|
||||
var v1 = getVal(l, params, symbol == "【");
|
||||
var v2 = getVal(r, params);
|
||||
|
||||
var res = 0;
|
||||
|
||||
if(symbol == "") {
|
||||
res = v1;
|
||||
} else if(symbol == "【") { //array builder
|
||||
res = array_create(array_length(v1));
|
||||
for( var i = 0; i < array_length(res); i++ )
|
||||
res[i] = getVal(v1[i], params);
|
||||
} else if(symbol == "@") {
|
||||
res = is_real(v2)? array_safe_get(v1, v2) : 0;
|
||||
} else if(is_array(v1) && !is_array(v2)) {
|
||||
res = array_create(array_length(v1));
|
||||
for( var i = 0; i < array_length(res); i++ )
|
||||
res[i] = eval_real(array_safe_get(v1, i), v2);
|
||||
} else if(!is_array(v1) && is_array(v2)) {
|
||||
res = array_create(array_length(v2));
|
||||
for( var i = 0; i < array_length(res); i++ )
|
||||
res[i] = eval_real(v1, array_safe_get(v2, i));
|
||||
} else if(is_array(v1) && is_array(v2)) {
|
||||
res = array_create(max(array_length(v1), array_length(v2)));
|
||||
for( var i = 0; i < array_length(res); i++ )
|
||||
res[i] = eval_real(array_safe_get(v1, i), array_safe_get(v2, i));
|
||||
} else
|
||||
res = eval_real(v1, v2);
|
||||
|
||||
//print($"|{v1}|{symbol}|{v2}| = {res}");
|
||||
//print($"symbol : {symbol}");
|
||||
//print($"l : {l}");
|
||||
//print($"r : {r}");
|
||||
//print($"l : | {typeof(l)} |{l}|");
|
||||
//print($"r : | {typeof(r)} |{r}|");
|
||||
//print("====================");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static eval_real = function(v1, v2) {
|
||||
switch(symbol) {
|
||||
case "+":
|
||||
if(_string(v1) || _string(v2))
|
||||
|
@ -165,7 +222,7 @@ function functionStringClean(fx) {
|
|||
case "∸": return is_real(v1)? -v1 : 0;
|
||||
case "*": return (is_real(v1) && is_real(v2))? v1 * v2 : 0;
|
||||
case "$": return (is_real(v1) && is_real(v2))? power(v1, v2) : 0;
|
||||
case "/": return (is_real(v1) && is_real(v2))? v1 / v2 : 0;
|
||||
case "/": return (is_real(v1) && is_real(v2) && v2 != 0)? v1 / v2 : 0;
|
||||
|
||||
case "&": return (is_real(v1) && is_real(v2))? v1 & v2 : 0;
|
||||
case "|": return (is_real(v1) && is_real(v2))? v1 | v2 : 0;
|
||||
|
@ -181,10 +238,6 @@ function functionStringClean(fx) {
|
|||
case ">": return (is_real(v1) && is_real(v2))? v1 > v2 : 0;
|
||||
case "<": return (is_real(v1) && is_real(v2))? v1 < v2 : 0;
|
||||
|
||||
case "@":
|
||||
var val = is_real(v2)? array_safe_get(v1, v2) : 0;
|
||||
return val;
|
||||
|
||||
case "sin" : return is_real(v1)? sin(v1) : 0;
|
||||
case "cos" : return is_real(v1)? cos(v1) : 0;
|
||||
case "tan" : return is_real(v1)? tan(v1) : 0;
|
||||
|
@ -204,6 +257,7 @@ function functionStringClean(fx) {
|
|||
var pres = global.EQUATION_PRES;
|
||||
var vl = ds_stack_create();
|
||||
var op = ds_stack_create();
|
||||
var last_push = "";
|
||||
|
||||
fx = functionStringClean(fx);
|
||||
|
||||
|
@ -224,52 +278,86 @@ function functionStringClean(fx) {
|
|||
if(ds_map_exists(pres, ch)) { //symbol is operator
|
||||
if(ds_stack_empty(op)) ds_stack_push(op, ch);
|
||||
else {
|
||||
if(pres[? ch] > pres[? ds_stack_top(op)] || ds_stack_top(op) == "(") ds_stack_push(op, ch);
|
||||
else {
|
||||
var _top = ds_stack_top(op);
|
||||
if(_top == "(" || ds_map_exists(global.FUNCTIONS, _top) || pres[? ch] > pres[? _top]) {
|
||||
ds_stack_push(op, ch);
|
||||
last_push = "op";
|
||||
} else {
|
||||
if(ch == "-" && ds_map_exists(pres, _ch)) ch = "∸"; //unary negative
|
||||
|
||||
while(pres[? ch] <= pres[? ds_stack_top(op)] && !ds_stack_empty(op))
|
||||
ds_stack_push(vl, buildFuncTree(ds_stack_pop(op), vl));
|
||||
ds_stack_push(op, ch);
|
||||
last_push = "op";
|
||||
}
|
||||
}
|
||||
|
||||
l++;
|
||||
} else if (ch == "(") {
|
||||
ds_stack_push(op, ch);
|
||||
if(last_push == "fn") ds_stack_push(op, [ "〚", ds_stack_size(vl) ]);
|
||||
else ds_stack_push(op, ch);
|
||||
last_push = "op";
|
||||
l++;
|
||||
} else if (ch == ")") {
|
||||
while(ds_stack_top(op) != "(" && !ds_stack_empty(op)) {
|
||||
ds_stack_push(vl, buildFuncTree(ds_stack_pop(op), vl));
|
||||
}
|
||||
ds_stack_pop(op);
|
||||
l++;
|
||||
//} else if (ch == "\"") {
|
||||
// l++;
|
||||
// var str = "";
|
||||
// while(l <= len) {
|
||||
// cch = string_char_at(fx, l);
|
||||
// if(cch == "\"") break;
|
||||
|
||||
// str += cch;
|
||||
// l++;
|
||||
// }
|
||||
// ds_stack_push(vl, str);
|
||||
} else if (ch == "[") {
|
||||
ds_stack_push(op, ch);
|
||||
l++;
|
||||
} else if (ch == "]") {
|
||||
while(ds_stack_top(op) != "[" && !ds_stack_empty(op))
|
||||
while(ds_stack_top(op) != "(" && !ds_stack_empty(op))
|
||||
ds_stack_push(vl, buildFuncTree(ds_stack_pop(op), vl));
|
||||
|
||||
ds_stack_pop(op);
|
||||
while(!ds_stack_empty(op)) {
|
||||
var _top = ds_stack_pop(op);
|
||||
if(_top == "(") break;
|
||||
if(is_array(_top) && _top[0] == "〚") {
|
||||
var arr = [];
|
||||
while(ds_stack_size(vl) > _top[1])
|
||||
array_insert(arr, 0, ds_stack_pop(vl));
|
||||
|
||||
ds_stack_push(vl, new __funcTree(ds_stack_pop(op), arr));
|
||||
break;
|
||||
}
|
||||
|
||||
ds_stack_push(vl, buildFuncTree(_top, vl));
|
||||
}
|
||||
|
||||
last_push = "vl";
|
||||
l++;
|
||||
} else if (ch == "[") {
|
||||
if(last_push == "vl") ds_stack_push(op, ch);
|
||||
else ds_stack_push(op, [ "{", ds_stack_size(vl) ]);
|
||||
last_push = "op";
|
||||
l++;
|
||||
} else if (ch == "]") {
|
||||
while(!ds_stack_empty(op)) {
|
||||
var _top = ds_stack_pop(op);
|
||||
if(_top == "[") break;
|
||||
if(is_array(_top) && _top[0] == "{") {
|
||||
var arr = [];
|
||||
while(ds_stack_size(vl) > _top[1])
|
||||
array_insert(arr, 0, ds_stack_pop(vl));
|
||||
ds_stack_push(vl, arr);
|
||||
break;
|
||||
}
|
||||
|
||||
ds_stack_push(vl, buildFuncTree(_top, vl));
|
||||
}
|
||||
|
||||
last_push = "vl";
|
||||
l++;
|
||||
} else if (ch == ",") {
|
||||
while(!ds_stack_empty(op)) {
|
||||
var _top = ds_stack_top(op);
|
||||
if(_top == "[" || _top == "(" || (is_array(_top) && _top[0] == "{")) break;
|
||||
|
||||
ds_stack_push(vl, buildFuncTree(_top, vl));
|
||||
ds_stack_pop(op);
|
||||
}
|
||||
|
||||
last_push = "vl";
|
||||
l++;
|
||||
} else {
|
||||
var vsl = "";
|
||||
|
||||
while(l <= len) {
|
||||
cch = string_char_at(fx, l);
|
||||
if(ds_map_exists(pres, cch) || array_exists(__BRACKETS, cch)) break;
|
||||
if(ds_map_exists(pres, cch) || array_exists(__BRACKETS, cch) || cch == ",") break;
|
||||
|
||||
vsl += cch;
|
||||
l++;
|
||||
|
@ -277,14 +365,18 @@ function functionStringClean(fx) {
|
|||
|
||||
if(vsl == "") continue;
|
||||
|
||||
if(ds_map_exists(pres, vsl)) {
|
||||
if(ds_map_exists(global.FUNCTIONS, vsl)) { //function
|
||||
ds_stack_push(op, vsl);
|
||||
last_push = "fn";
|
||||
} else {
|
||||
vsl = string_trim(vsl);
|
||||
switch(vsl) {
|
||||
case "e" : ds_stack_push(vl, 2.71828); break;
|
||||
case "pi": ds_stack_push(vl, pi); break;
|
||||
default : ds_stack_push(vl, isNumber(vsl)? toNumber(vsl) : vsl); break;
|
||||
}
|
||||
|
||||
last_push = "vl";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,9 +390,14 @@ function functionStringClean(fx) {
|
|||
var tree = ds_stack_empty(vl)? noone : ds_stack_pop(vl)
|
||||
ds_stack_destroy(vl);
|
||||
|
||||
if(is_string(tree))
|
||||
if(!is_struct(tree))
|
||||
tree = new __funcTree("", tree);
|
||||
|
||||
print("=====");
|
||||
print(fx);
|
||||
print(tree);
|
||||
print("");
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
|
@ -316,11 +413,19 @@ function functionStringClean(fx) {
|
|||
} else
|
||||
return new __funcTree("-", ds_stack_pop(vl), 0);
|
||||
|
||||
case "@":
|
||||
var _v1 = ds_stack_pop(vl);
|
||||
if(is_array(_v1))
|
||||
return new __funcTree("【", _v1);
|
||||
else {
|
||||
var _v2 = ds_stack_pop(vl);
|
||||
return new __funcTree(operator, _v2, _v1);
|
||||
}
|
||||
|
||||
case "+": //binary operators
|
||||
case "*":
|
||||
case "$":
|
||||
case "/":
|
||||
case "@":
|
||||
|
||||
case "|":
|
||||
case "&":
|
||||
|
|
|
@ -14,8 +14,9 @@ const float ContrastAmount = 150.0;
|
|||
const vec3 ContrastFactor = vec3(9.0);
|
||||
const float Smooth = 2.0;
|
||||
|
||||
vec3 bokeh(sampler2D tex, vec2 uv, float radius) {
|
||||
vec4 bokeh(sampler2D tex, vec2 uv, float radius) {
|
||||
vec3 num, weight;
|
||||
float alpha = 0.;
|
||||
float rec = 1.0; // reciprocal
|
||||
vec2 horizontalAngle = vec2(0.0, radius * 0.01 / sqrt(Iterations));
|
||||
vec2 aspect = vec2(dimension.y / dimension.x, 1.0);
|
||||
|
@ -29,19 +30,22 @@ vec3 bokeh(sampler2D tex, vec2 uv, float radius) {
|
|||
rec += 1.0 / rec;
|
||||
horizontalAngle = horizontalAngle * Rotation;
|
||||
|
||||
vec2 offset = (rec - 1.0) * horizontalAngle;
|
||||
vec2 offset = (rec - 1.0) * horizontalAngle;
|
||||
vec2 sampleUV = uv + aspect * offset;
|
||||
vec3 col = texture2D(tex, sampleUV).rgb;
|
||||
vec4 sam = texture2D(tex, sampleUV);
|
||||
vec3 col = sam.rgb * sam.a;
|
||||
|
||||
// increase contrast and smooth
|
||||
vec3 bokeh = Smooth + pow(col, ContrastFactor) * ContrastAmount;
|
||||
|
||||
num += col * bokeh;
|
||||
weight += bokeh;
|
||||
|
||||
num += col * bokeh;
|
||||
alpha += sam.a * (bokeh.r + bokeh.g + bokeh.b) / 3.;
|
||||
weight += bokeh;
|
||||
}
|
||||
return num / weight;
|
||||
|
||||
return vec4(num / weight, alpha / ((weight.r + weight.g + weight.b) / 3.));
|
||||
}
|
||||
|
||||
void main() {
|
||||
gl_FragColor = vec4(bokeh(gm_BaseTexture, v_vTexcoord, strength), 1.0);
|
||||
gl_FragColor = bokeh(gm_BaseTexture, v_vTexcoord, strength);
|
||||
}
|
||||
|
|
|
@ -10,9 +10,16 @@ uniform vec2 scnDimension;
|
|||
uniform vec2 camDimension;
|
||||
uniform vec2 position;
|
||||
uniform float zoom;
|
||||
uniform float blur;
|
||||
uniform int sampleMode;
|
||||
uniform int fixBG;
|
||||
uniform int bg;
|
||||
uniform float bokehStrength;
|
||||
|
||||
const float GoldenAngle = 2.39996323;
|
||||
const float Iterations = 400.0;
|
||||
|
||||
const float ContrastAmount = 150.0;
|
||||
const vec3 ContrastFactor = vec3(9.0);
|
||||
const float Smooth = 2.0;
|
||||
|
||||
vec4 sampleTexture(sampler2D samp, vec2 pos) {
|
||||
if(pos.x >= 0. && pos.y >= 0. && pos.x <= 1. && pos.y <= 1.)
|
||||
|
@ -20,19 +27,57 @@ vec4 sampleTexture(sampler2D samp, vec2 pos) {
|
|||
|
||||
if(sampleMode == 0)
|
||||
return vec4(0.);
|
||||
if(sampleMode == 1)
|
||||
else if(sampleMode == 1)
|
||||
return texture2D(samp, fract(pos));
|
||||
else if(sampleMode == 2)
|
||||
return texture2D(samp, vec2(fract(pos.x), pos.y));
|
||||
else if(sampleMode == 3)
|
||||
return texture2D(samp, vec2(pos.x, fract(pos.y)));
|
||||
|
||||
return vec4(0.);
|
||||
}
|
||||
|
||||
vec4 bokeh(sampler2D tex, vec2 uv, float radius) { //ref. sh_blur_bokeh
|
||||
vec3 num, weight;
|
||||
float alpha = 0.;
|
||||
float rec = 1.0; // reciprocal
|
||||
vec2 horizontalAngle = vec2(0.0, radius * 0.01 / sqrt(Iterations));
|
||||
vec2 aspect = vec2(scnDimension.y / scnDimension.x, 1.0);
|
||||
|
||||
mat2 Rotation = mat2(
|
||||
cos(GoldenAngle), sin(GoldenAngle),
|
||||
-sin(GoldenAngle), cos(GoldenAngle)
|
||||
);
|
||||
|
||||
for (float i; i < Iterations; i++) {
|
||||
rec += 1.0 / rec;
|
||||
horizontalAngle = horizontalAngle * Rotation;
|
||||
|
||||
vec2 offset = (rec - 1.0) * horizontalAngle;
|
||||
vec2 sampleUV = uv + aspect * offset;
|
||||
vec4 sam = sampleTexture(tex, sampleUV);
|
||||
vec3 col = sam.rgb * sam.a;
|
||||
|
||||
// increase contrast and smooth
|
||||
vec3 bokeh = Smooth + pow(col, ContrastFactor) * ContrastAmount;
|
||||
|
||||
num += col * bokeh;
|
||||
alpha += sam.a * (bokeh.r + bokeh.g + bokeh.b) / 3.;
|
||||
weight += bokeh;
|
||||
}
|
||||
|
||||
return vec4(num / weight, alpha / ((weight.r + weight.g + weight.b) / 3.));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 pos = position + (v_vTexcoord - vec2(.5)) * (camDimension / scnDimension) * zoom;
|
||||
vec4 _col0 = sampleTexture( scene, pos );
|
||||
vec4 _col1 = sampleTexture( backg, fixBG == 1? v_vTexcoord - position + vec2(.5) : pos );
|
||||
if(bg == 1) pos = position + v_vTexcoord - vec2(.5);
|
||||
vec4 _col0 = sampleTexture( backg, v_vTexcoord );
|
||||
vec4 _col1 = bokeh( scene, pos, bokehStrength );
|
||||
|
||||
float al = _col0.a + _col1.a * (1. - _col0.a);
|
||||
vec4 res = ((_col0 * _col0.a) + (_col1 * _col1.a * (1. - _col0.a))) / al;
|
||||
float al = _col1.a + _col0.a * (1. - _col1.a);
|
||||
vec4 res = _col0 * _col0.a * (1. - _col1.a) + _col1 * _col1.a;
|
||||
res /= al;
|
||||
res.a = al;
|
||||
|
||||
gl_FragColor = res;
|
||||
|
|
Loading…
Reference in a new issue