- New RM Combine node.

This commit is contained in:
Tanasart 2024-06-14 17:46:25 +07:00
parent c5fcb15580
commit f55e8cc376
24 changed files with 909 additions and 250 deletions

View file

@ -57,7 +57,7 @@
{"name":"drawer","order":11,"path":"folders/nodes/data/generator/drawer.yy",},
{"name":"noise","order":14,"path":"folders/nodes/data/generator/noise.yy",},
{"name":"pattern","order":15,"path":"folders/nodes/data/generator/pattern.yy",},
{"name":"ray march","order":21,"path":"folders/nodes/data/generator/ray march.yy",},
{"name":"raymarching","order":13,"path":"folders/nodes/data/3D/raymarching.yy",},
{"name":"regions","order":19,"path":"folders/nodes/data/generator/regions.yy",},
{"name":"group","order":18,"path":"folders/nodes/data/group.yy",},
{"name":"io","order":19,"path":"folders/nodes/data/io.yy",},
@ -166,11 +166,11 @@
{"name":"blinker","order":19,"path":"folders/shader/generator/blinker.yy",},
{"name":"cell","order":20,"path":"folders/shader/generator/cell.yy",},
{"name":"grid","order":18,"path":"folders/shader/generator/grid.yy",},
{"name":"texture repeat","order":28,"path":"folders/shader/generator/texture repeat.yy",},
{"name":"interpret","order":17,"path":"folders/shader/generator/interpret.yy",},
{"name":"random_shape","order":21,"path":"folders/shader/generator/random_shape.yy",},
{"name":"reaction_diffusion","order":22,"path":"folders/shader/generator/reaction_diffusion.yy",},
{"name":"region","order":23,"path":"folders/shader/generator/region.yy",},
{"name":"texture repeat","order":28,"path":"folders/shader/generator/texture repeat.yy",},
{"name":"vector_mapper","order":24,"path":"folders/shader/generator/vector_mapper.yy",},
{"name":"mask","order":10,"path":"folders/shader/mask.yy",},
{"name":"misc","order":11,"path":"folders/shader/misc.yy",},
@ -346,6 +346,7 @@
{"name":"__path","order":1,"path":"scripts/__path/__path.yy",},
{"name":"__pbBox","order":3,"path":"scripts/__pbBox/__pbBox.yy",},
{"name":"__polygon","order":2,"path":"scripts/__polygon/__polygon.yy",},
{"name":"__raymarching","order":4,"path":"scripts/__raymarching/__raymarching.yy",},
{"name":"__rectangle","order":7,"path":"scripts/__rectangle/__rectangle.yy",},
{"name":"__shapes","order":3,"path":"scripts/__shapes/__shapes.yy",},
{"name":"__sliderRange","order":3,"path":"scripts/__sliderRange/__sliderRange.yy",},
@ -1002,6 +1003,7 @@
{"name":"node_rigid_variable","order":11,"path":"scripts/node_rigid_variable/node_rigid_variable.yy",},
{"name":"node_rigid_wall","order":12,"path":"scripts/node_rigid_wall/node_rigid_wall.yy",},
{"name":"node_rim","order":22,"path":"scripts/node_rim/node_rim.yy",},
{"name":"node_rm_combine","order":3,"path":"scripts/node_rm_combine/node_rm_combine.yy",},
{"name":"node_rm_primitive","order":1,"path":"scripts/node_rm_primitive/node_rm_primitive.yy",},
{"name":"node_rm_terrain","order":2,"path":"scripts/node_rm_terrain/node_rm_terrain.yy",},
{"name":"node_sampler","order":3,"path":"scripts/node_sampler/node_sampler.yy",},
@ -1971,6 +1973,7 @@
{"name":"s_node_rigidSim_render_output","order":10,"path":"sprites/s_node_rigidSim_render_output/s_node_rigidSim_render_output.yy",},
{"name":"s_node_rigidSim_renderer","order":1,"path":"sprites/s_node_rigidSim_renderer/s_node_rigidSim_renderer.yy",},
{"name":"s_node_rigidSim_wall","order":11,"path":"sprites/s_node_rigidSim_wall/s_node_rigidSim_wall.yy",},
{"name":"s_node_rm_combine","order":26,"path":"sprites/s_node_rm_combine/s_node_rm_combine.yy",},
{"name":"s_node_rm_primitive","order":51,"path":"sprites/s_node_rm_primitive/s_node_rm_primitive.yy",},
{"name":"s_node_rm_terrain","order":52,"path":"sprites/s_node_rm_terrain/s_node_rm_terrain.yy",},
{"name":"s_node_sampler","order":19,"path":"sprites/s_node_sampler/s_node_sampler.yy",},

View file

@ -155,7 +155,7 @@
{"$GMFolder":"","%Name":"drawer","folderPath":"folders/nodes/data/generator/drawer.yy","name":"drawer","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"noise","folderPath":"folders/nodes/data/generator/noise.yy","name":"noise","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"pattern","folderPath":"folders/nodes/data/generator/pattern.yy","name":"pattern","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"ray march","folderPath":"folders/nodes/data/generator/ray march.yy","name":"ray march","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"raymarching","folderPath":"folders/nodes/data/3D/raymarching.yy","name":"raymarching","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"regions","folderPath":"folders/nodes/data/generator/regions.yy","name":"regions","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"group","folderPath":"folders/nodes/data/group.yy","name":"group","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"io","folderPath":"folders/nodes/data/io.yy","name":"io","resourceType":"GMFolder","resourceVersion":"2.0",},
@ -288,11 +288,11 @@
{"$GMFolder":"","%Name":"blinker","folderPath":"folders/shader/generator/blinker.yy","name":"blinker","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"cell","folderPath":"folders/shader/generator/cell.yy","name":"cell","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"grid","folderPath":"folders/shader/generator/grid.yy","name":"grid","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"texture repeat","folderPath":"folders/shader/generator/texture repeat.yy","name":"texture repeat","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"interpret","folderPath":"folders/shader/generator/interpret.yy","name":"interpret","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"random_shape","folderPath":"folders/shader/generator/random_shape.yy","name":"random_shape","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"reaction_diffusion","folderPath":"folders/shader/generator/reaction_diffusion.yy","name":"reaction_diffusion","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"region","folderPath":"folders/shader/generator/region.yy","name":"region","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"texture repeat","folderPath":"folders/shader/generator/texture repeat.yy","name":"texture repeat","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"vector_mapper","folderPath":"folders/shader/generator/vector_mapper.yy","name":"vector_mapper","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"mask","folderPath":"folders/shader/mask.yy","name":"mask","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"misc","folderPath":"folders/shader/misc.yy","name":"misc","resourceType":"GMFolder","resourceVersion":"2.0",},
@ -670,6 +670,7 @@
{"id":{"name":"__path","path":"scripts/__path/__path.yy",},},
{"id":{"name":"__pbBox","path":"scripts/__pbBox/__pbBox.yy",},},
{"id":{"name":"__polygon","path":"scripts/__polygon/__polygon.yy",},},
{"id":{"name":"__raymarching","path":"scripts/__raymarching/__raymarching.yy",},},
{"id":{"name":"__rectangle","path":"scripts/__rectangle/__rectangle.yy",},},
{"id":{"name":"__shapes","path":"scripts/__shapes/__shapes.yy",},},
{"id":{"name":"__sliderRange","path":"scripts/__sliderRange/__sliderRange.yy",},},
@ -1431,6 +1432,7 @@
{"id":{"name":"node_rigid_variable","path":"scripts/node_rigid_variable/node_rigid_variable.yy",},},
{"id":{"name":"node_rigid_wall","path":"scripts/node_rigid_wall/node_rigid_wall.yy",},},
{"id":{"name":"node_rim","path":"scripts/node_rim/node_rim.yy",},},
{"id":{"name":"node_rm_combine","path":"scripts/node_rm_combine/node_rm_combine.yy",},},
{"id":{"name":"node_rm_primitive","path":"scripts/node_rm_primitive/node_rm_primitive.yy",},},
{"id":{"name":"node_rm_terrain","path":"scripts/node_rm_terrain/node_rm_terrain.yy",},},
{"id":{"name":"node_sampler","path":"scripts/node_sampler/node_sampler.yy",},},
@ -2537,6 +2539,7 @@
{"id":{"name":"s_node_rigidSim_renderer","path":"sprites/s_node_rigidSim_renderer/s_node_rigidSim_renderer.yy",},},
{"id":{"name":"s_node_rigidSim_wall","path":"sprites/s_node_rigidSim_wall/s_node_rigidSim_wall.yy",},},
{"id":{"name":"s_node_rigidSim","path":"sprites/s_node_rigidSim/s_node_rigidSim.yy",},},
{"id":{"name":"s_node_rm_combine","path":"sprites/s_node_rm_combine/s_node_rm_combine.yy",},},
{"id":{"name":"s_node_rm_primitive","path":"sprites/s_node_rm_primitive/s_node_rm_primitive.yy",},},
{"id":{"name":"s_node_rm_terrain","path":"sprites/s_node_rm_terrain/s_node_rm_terrain.yy",},},
{"id":{"name":"s_node_sampler","path":"sprites/s_node_sampler/s_node_sampler.yy",},},

View file

@ -571,8 +571,8 @@ enum CAMERA_PROJ {
shader_set(shader);
shader_set_uniform_f_array_safe(uniVertex_lightFor, lightFor);
shader_set_uniform_f_array_safe(uniLightAmb, colorArrayFromReal(_aclr));
shader_set_uniform_f_array_safe(uniLightClr, colorArrayFromReal(_lclr));
shader_set_uniform_f_array_safe(uniLightAmb, colorToArray(_aclr));
shader_set_uniform_f_array_safe(uniLightClr, colorToArray(_lclr));
shader_set_uniform_f(uniLightInt, _lint);
shader_set_uniform_i(uniLightNrm, use_normal);

View file

@ -0,0 +1,195 @@
function RM_Object() constructor {
id = UUID_generate();
shapeAmount = 0;
shape = [];
size = [];
radius = [];
thickness = [];
crop = [];
angle = [];
height = [];
radRange = [];
sizeUni = [];
elongate = [];
rounded = [];
corner = [];
size2D = [];
sides = [];
waveAmp = [];
waveInt = [];
waveShift = [];
twistAxis = [];
twistAmount = [];
position = [];
rotation = [];
objectScale = [];
tileSize = [];
tileAmount = [];
diffuseColor = [];
reflective = [];
volumetric = [];
volumeDensity = [];
texture = [];
useTexture = [];
textureScale = [];
triplanar = [];
opmap = -1;
uniformKeys = [ "shape", "size", "radius", "thickness", "crop", "angle", "height", "radRange", "sizeUni", "elongate", "rounded", "corner", "size2D", "sides",
"waveAmp", "waveInt", "waveShift",
"twistAxis", "twistAmount",
"position", "rotation", "objectScale",
"tileSize", "tileAmount",
"diffuseColor", "reflective",
"volumetric", "volumeDensity",
"texture", "useTexture", "textureScale", "triplanar"
];
textureAtl = noone;
static setTexture = function(textureAtlas) {
var tx = 1024;
surface_set_shader(textureAtlas);
for (var i = 0; i < shapeAmount; i++)
draw_surface_stretched_safe(texture[i], tx * (i % 8), tx * floor(i / 8), tx, tx);
surface_reset_shader();
textureAtl = textureAtlas;
}
static apply = function() {
// print(self);
shader_set_i("shapeAmount", shapeAmount);
if(shapeAmount <= 0) return;
shader_set_i("operations", opmap);
shader_set_i("opLength", array_safe_length(opmap));
shader_set_i("shape", shape);
shader_set_f("size", size);
shader_set_f("radius", radius);
shader_set_f("thickness", thickness);
shader_set_f("crop", crop);
shader_set_f("angle", angle);
shader_set_f("height", height);
shader_set_f("radRange", radRange);
shader_set_f("sizeUni", sizeUni);
shader_set_f("elongate", elongate);
shader_set_f("rounded", rounded);
shader_set_f("corner", corner);
shader_set_f("size2D", size2D);
shader_set_i("sides", sides);
shader_set_f("waveAmp", waveAmp);
shader_set_f("waveInt", waveInt);
shader_set_f("waveShift", waveShift);
shader_set_i("twistAxis", twistAxis);
shader_set_f("twistAmount", twistAmount);
shader_set_f("position", position);
shader_set_f("rotation", rotation);
shader_set_f("objectScale", objectScale);
shader_set_f("tileSize", tileSize);
shader_set_f("tileAmount", tileAmount);
shader_set_f("diffuseColor", diffuseColor);
shader_set_f("reflective", reflective);
shader_set_i("volumetric", volumetric);
shader_set_f("volumeDensity", volumeDensity);
///////////////////////////////////////////////////////////////
shader_set_surface("texture1", textureAtl);
shader_set_i("useTexture", useTexture);
shader_set_f("textureScale", textureScale);
shader_set_f("triplanar", triplanar);
}
}
function RM_Operation(type, left, right) : RM_Object() constructor {
self.type = type;
self.left = left;
self.right = right;
static reset = function() {
for (var i = 0, n = array_length(uniformKeys); i < n; i++)
self[$ uniformKeys[i]] = [];
}
static add = function(rmObject) {
for (var i = 0, n = array_length(uniformKeys); i < n; i++)
array_append(self[$ uniformKeys[i]], rmObject[$ uniformKeys[i]]);
}
static __flatten = function(node) {
if(is_instanceof(node, RM_Shape))
return node;
var _op = node.type;
var _l = node.left;
var _r = node.right;
var _arr = [ ];
array_append(_arr, __flatten(_l));
array_append(_arr, __flatten(_r));
array_push(_arr, _op);
return _arr;
}
static flatten = function() {
var _arr = __flatten(self);
var _nodes = [];
for (var i = 0, n = array_length(_arr); i < n; i++) {
var _a = _arr[i];
if(!is_struct(_a)) continue;
if(array_exists(_nodes, _a)) continue;
_a.flatten_index = array_length(_nodes);
array_push(_nodes, _a);
}
opmap = [];
for (var i = 0, n = array_length(_arr); i < n; i++) {
var _a = _arr[i];
if(is_string(_a)) {
switch(_a) {
case "combine" : array_push(opmap, 100); break;
}
} else if(is_struct(_a))
array_push(opmap, _a.flatten_index);
}
// print(opmap);
shapeAmount = array_length(_nodes);
reset();
for (var i = 0, n = array_length(_nodes); i < n; i++)
add(_nodes[i]);
}
}
function RM_Shape() : RM_Object() constructor {
}

View file

@ -0,0 +1,13 @@
{
"$GMScript":"",
"%Name":"__raymarching",
"isCompatibility":false,
"isDnD":false,
"name":"__raymarching",
"parent":{
"name":"raymarching",
"path":"folders/nodes/data/3D/raymarching.yy",
},
"resourceType":"GMScript",
"resourceVersion":"2.0",
}

View file

@ -188,7 +188,7 @@ function array_append(arr, arr0) { #region
INLINE
if(!is_array(arr)) return arr;
if(!is_array(arr0)) return arr;
if(!is_array(arr0)) { array_push(arr, arr0); return arr; }
for( var i = 0, n = array_length(arr0); i < n; i++ )
array_push(arr, arr0[i]);

View file

@ -53,8 +53,9 @@
return make_color_rgb(r, g, b);
} #endregion
function colorArrayFromReal(clr) { #region
function colorToArray(clr, alpha = false) { #region
INLINE
if(alpha) return [ _color_get_red(clr), _color_get_green(clr), _color_get_blue(clr), _color_get_alpha(clr) ];
return [ _color_get_red(clr), _color_get_green(clr), _color_get_blue(clr) ];
} #endregion

View file

@ -38,7 +38,7 @@
LATEST_VERSION = 11700;
VERSION = 11740;
SAVE_VERSION = 11700;
VERSION_STRING = "1.17.4.002";
VERSION_STRING = "1.17.4.003";
BUILD_NUMBER = 11740;
globalvar HOTKEYS, HOTKEY_CONTEXT;

View file

@ -96,9 +96,9 @@ function Node_Gradient_Points(_x, _y, _group = noone) : Node_Processor(_x, _y, _
if(_usePal) {
for( var i = 0; i < 4; i++ )
colArr = array_append(colArr, colorArrayFromReal(array_safe_get_fast(_pal, i, c_black)));
colArr = array_append(colArr, colorToArray(array_safe_get_fast(_pal, i, c_black)));
} else
colArr = array_merge(colorArrayFromReal(_1col), colorArrayFromReal(_2col), colorArrayFromReal(_3col), colorArrayFromReal(_4col))
colArr = array_merge(colorToArray(_1col), colorToArray(_2col), colorToArray(_3col), colorToArray(_4col))
surface_set_shader(_outSurf, sh_gradient_points);

View file

@ -765,6 +765,7 @@ function __initNodes() {
ds_list_add(generator, "Ray Marching");
addNodeObject(generator, "RM Primitive", s_node_rm_primitive, "Node_RM_Primitive", [1, Node_RM_Primitive], ["ray marching"]).setVersion(11720);
addNodeObject(generator, "RM Terrain", s_node_rm_terrain, "Node_RM_Terrain", [1, Node_RM_Terrain], ["ray marching"]).setVersion(11720);
addNodeObject(generator, "RM Combine", s_node_rm_combine, "Node_RM_Combine", [1, Node_RM_Combine], ["ray marching"]).setVersion(11740);
ds_list_add(generator, "MK Effects");
addNodeObject(generator, "MK Rain", s_node_mk_rain, "Node_MK_Rain", [1, Node_MK_Rain]).setVersion(11600);

View file

@ -0,0 +1,120 @@
function Node_RM_Combine(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
name = "RM Combine";
batch_output = true;
inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF)
.setDisplay(VALUE_DISPLAY.vector);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
inputs[| 1] = nodeValue("Projection", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
.setDisplay(VALUE_DISPLAY.enum_button, [ "Perspective", "Orthographic" ])
.setVisible(false, false);
inputs[| 2] = nodeValue("FOV", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 30)
.setDisplay(VALUE_DISPLAY.slider, { range: [ 0, 90, 1 ] });
inputs[| 3] = nodeValue("Ortho Scale", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 5.)
inputs[| 4] = nodeValue("View Range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 3, 6 ])
.setDisplay(VALUE_DISPLAY.vector);
inputs[| 5] = nodeValue("Depth", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0)
.setDisplay(VALUE_DISPLAY.slider);
inputs[| 6] = nodeValue("Draw BG", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true);
inputs[| 7] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_black);
inputs[| 8] = nodeValue("Ambient Level", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.2)
.setDisplay(VALUE_DISPLAY.slider);
inputs[| 9] = nodeValue("Light Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ -.5, -.5, 1 ])
.setDisplay(VALUE_DISPLAY.vector);
inputs[| 10] = nodeValue("Environment", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, false);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
inputs[| 11] = nodeValue("Shape 1", self, JUNCTION_CONNECT.input, VALUE_TYPE.struct, {})
.setVisible(true, true);
inputs[| 12] = nodeValue("Shape 2", self, JUNCTION_CONNECT.input, VALUE_TYPE.struct, {})
.setVisible(true, true);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
outputs[| 0] = nodeValue("Surface Out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
outputs[| 1] = nodeValue("Shape Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.struct, noone);
input_display_list = [ 0,
["Camera", false], 1, 2, 3, 4, 5,
["Render", false], 6, 7, 8, 10, 9,
["Shapes", false], 11, 12,
]
temp_surface = [ 0, 0 ];
static processData = function(_outSurf, _data, _output_index, _array_index = 0) {
var _dim = _data[0];
var _pro = _data[1];
var _fov = _data[2];
var _ort = _data[3];
var _vrn = _data[4];
var _dep = _data[5];
var _bgd = _data[6];
var _bgc = _data[7];
var _amb = _data[8];
var _lig = _data[9];
var _env = _data[10];
var _sh0 = _data[11];
var _sh1 = _data[12];
if(!is_instanceof(_sh0, RM_Object)) return [ _outSurf, noone ];
if(!is_instanceof(_sh1, RM_Object)) return [ _outSurf, noone ];
_outSurf = surface_verify(_outSurf, _dim[0], _dim[1]);
for (var i = 0, n = array_length(temp_surface); i < n; i++)
temp_surface[i] = surface_verify(temp_surface[i], 8192, 8192);
var tx = 1024;
surface_set_shader(temp_surface[0]);
draw_surface_stretched_safe(_env, tx * 0, tx * 0, tx, tx);
surface_reset_shader();
var object = new RM_Operation("combine", _sh0, _sh1);
object.flatten();
object.setTexture(temp_surface[1]);
gpu_set_texfilter(true);
surface_set_shader(_outSurf, sh_rm_primitive);
shader_set_surface($"texture0", temp_surface[0]);
shader_set_i("ortho", _pro);
shader_set_f("fov", _fov);
shader_set_f("orthoScale", _ort);
shader_set_f("viewRange", _vrn);
shader_set_f("depthInt", _dep);
shader_set_i("drawBg", _bgd);
shader_set_color("background", _bgc);
shader_set_f("ambientIntns", _amb);
shader_set_f("lightPosition", _lig);
shader_set_i("useEnv", is_surface(_env));
object.apply();
draw_sprite_stretched(s_fx_pixel, 0, 0, 0, _dim[0], _dim[1]);
surface_reset_shader();
gpu_set_texfilter(false);
return [ _outSurf, object ];
}
}

View file

@ -0,0 +1,13 @@
{
"$GMScript":"",
"%Name":"node_rm_combine",
"isCompatibility":false,
"isDnD":false,
"name":"node_rm_combine",
"parent":{
"name":"raymarching",
"path":"folders/nodes/data/3D/raymarching.yy",
},
"resourceType":"GMScript",
"resourceVersion":"2.0",
}

View file

@ -1,15 +1,16 @@
function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
name = "RM Primitive";
batch_output = true;
inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF)
.setDisplay(VALUE_DISPLAY.vector);
shape_types = [
"Plane", "Box", "Box Frame",
"Plane", "Box", "Box Frame", "Box Round",
-1,
"Sphere", "Ellipse", "Cut Sphere", "Cut Hollow Sphere", "Torus", "Capped Torus",
-1,
"Cylinder", "Capsule", "Cone", "Capped Cone", "Round Cone", "3D Arc",
"Cylinder", "Prism", "Capsule", "Cone", "Capped Cone", "Round Cone", "3D Arc",
-1,
"Octahedron", "Pyramid",
];
@ -102,8 +103,8 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
inputs[| 26] = nodeValue("Height", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, .5)
.setDisplay(VALUE_DISPLAY.slider);
inputs[| 27] = nodeValue("Radius Range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, .7)
.setDisplay(VALUE_DISPLAY.slider);
inputs[| 27] = nodeValue("Radius Range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ .7, .1 ])
.setDisplay(VALUE_DISPLAY.slider_range);
inputs[| 28] = nodeValue("Uniform Size", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1)
.setDisplay(VALUE_DISPLAY.slider);
@ -136,10 +137,22 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
inputs[| 38] = nodeValue("Texture Scale", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1.);
inputs[| 39] = nodeValue("Corner", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0.25, 0.25, 0.25, 0.25 ])
.setDisplay(VALUE_DISPLAY.vector);
inputs[| 40] = nodeValue("2D Size", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0.5, 0.5 ])
.setDisplay(VALUE_DISPLAY.vector);
inputs[| 41] = nodeValue("Side", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 3);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
outputs[| 0] = nodeValue("Surface Out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
outputs[| 1] = nodeValue("Shape Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.struct, noone);
input_display_list = [ 0,
["Primitive", false], 1, 21, 22, 23, 24, 25, 26, 27, 28,
["Primitive", false], 1, 21, 22, 23, 24, 25, 26, 27, 28, 39, 40, 41,
["Modify", false], 12, 11,
["Deform", true], 15, 16, 17, 18, 19,
["Transform", false], 2, 3, 4,
@ -150,7 +163,8 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
["Volumetric", true, 32], 33,
];
temp_surface = [ 0, 0, 0, 0 ];
temp_surface = [ 0, 0 ];
object = new RM_Shape();
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {}
@ -166,6 +180,9 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
inputs[| 26].setVisible(false);
inputs[| 27].setVisible(false);
inputs[| 28].setVisible(false);
inputs[| 39].setVisible(false);
inputs[| 40].setVisible(false);
inputs[| 41].setVisible(false);
var _shape = shape_types[_shp];
switch(_shape) { // Size
@ -191,11 +208,13 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
switch(_shape) { // Thickness
case "Box Frame" :
case "Box Round" :
case "Torus" :
case "Cut Hollow Sphere" :
case "Capped Torus" :
case "Terrain" :
case "Extrude" :
case "Prism" :
inputs[| 23].setVisible(true);
break;
}
@ -241,6 +260,24 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
break;
}
switch(_shape) { // Corner
case "Box Round" :
inputs[| 39].setVisible(true);
break;
}
switch(_shape) { // Size 2D
case "Box Round" :
inputs[| 40].setVisible(true);
break;
}
switch(_shape) { // Sides
case "Prism" :
inputs[| 41].setVisible(true);
break;
}
inputs[| 5].setVisible(_ort == 0);
inputs[| 14].setVisible(_ort == 1);
}
@ -293,6 +330,9 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
var _text = _data[36];
var _triS = _data[37];
var _texs = _data[38];
var _corn = _data[39];
var _sz2d = _data[40];
var _side = _data[41];
_outSurf = surface_verify(_outSurf, _dim[0], _dim[1]);
@ -302,13 +342,8 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
var tx = 1024;
surface_set_shader(temp_surface[0]);
draw_surface_stretched_safe(bgEnv, tx * 0, tx * 0, tx, tx);
draw_surface_stretched_safe(_text, tx * 1, tx * 0, tx, tx);
surface_reset_shader();
gpu_set_texfilter(true);
surface_set_shader(_outSurf, sh_rm_primitive);
var _shape = shape_types[_shp];
var _shpI = 0;
@ -316,6 +351,7 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
case "Plane" : _shpI = 100; break;
case "Box" : _shpI = 101; break;
case "Box Frame" : _shpI = 102; break;
case "Box Round" : _shpI = 103; break;
case "Sphere" : _shpI = 200; break;
case "Ellipse" : _shpI = 201; break;
@ -330,68 +366,81 @@ function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
case "Capped Cone" : _shpI = 303; break;
case "Round Cone" : _shpI = 304; break;
case "3D Arc" : _shpI = 305; break;
case "Prism" : _shpI = 306; break;
case "Octahedron" : _shpI = 400; break;
case "Pyramid" : _shpI = 401; break;
}
for (var i = 0, n = array_length(temp_surface); i < n; i++)
shader_set_surface($"texture{i}", temp_surface[i]);
object.operations = -1;
object.shapeAmount = 1;
shader_set_f("time", CURRENT_FRAME / TOTAL_FRAMES);
object.shape = _shpI;
object.size = _size;
object.radius = _rad ;
object.thickness = _thk ;
object.crop = _crop;
object.angle = degtorad(_angl);
object.height = _heig;
object.radRange = _radR;
object.sizeUni = _sizz;
object.elongate = _elon;
object.rounded = _rond;
object.corner = _corn;
object.size2D = _sz2d;
object.sides = _side;
shader_set_i("shape", _shpI);
shader_set_f("size", _size);
shader_set_f("radius", _rad);
shader_set_f("thickness", _thk);
shader_set_f("crop", _crop);
shader_set_f("angle", degtorad(_angl));
shader_set_f("height", _heig);
shader_set_f("radRange", _radR);
shader_set_f("sizeUni", _sizz);
shader_set_f("elongate", _elon);
shader_set_f("rounded", _rond);
object.waveAmp = _wavA;
object.waveInt = _wavI;
object.waveShift = _wavS;
shader_set_f("waveAmp", _wavA);
shader_set_f("waveInt", _wavI);
shader_set_f("waveShift", _wavS);
object.twistAxis = _twsX;
object.twistAmount = _twsA;
shader_set_i("twistAxis", _twsX);
shader_set_f("twistAmount", _twsA);
object.position = _pos;
object.rotation = _rot;
object.objectScale = _sca;
shader_set_f("position", _pos);
shader_set_f("rotation", _rot);
shader_set_f("objectScale", _sca);
object.tileSize = _tile;
object.tileAmount = _tilA;
object.diffuseColor = colorToArray(_amb, true);
object.reflective = _refl;
object.volumetric = _vol;
object.volumeDensity = _vden;
object.texture = [ _text ];
object.useTexture = is_surface(_text);
object.textureScale = _texs;
object.triplanar = _triS;
object.setTexture(temp_surface[1]);
gpu_set_texfilter(true);
surface_set_shader(_outSurf, sh_rm_primitive);
shader_set_surface($"texture0", temp_surface[0]);
shader_set_i("ortho", _ort);
shader_set_f("fov", _fov);
shader_set_f("orthoScale", _ortS);
shader_set_f("viewRange", _rng);
shader_set_f("depthInt", _dpi);
shader_set_f("tileSize", _tile);
shader_set_f("tileAmount", _tilA);
shader_set_i("drawBg", _bgd);
shader_set_color("background", _bgc);
shader_set_f("ambientIntns", _ambI);
shader_set_f("lightPosition", _lPos);
shader_set_color("ambient", _amb);
shader_set_f("reflective", _refl);
shader_set_i("volumetric", _vol);
shader_set_f("volumeDensity", _vden);
shader_set_f("triplanar", _triS);
shader_set_f("textureScale", _texs);
shader_set_i("useEnv", is_surface(bgEnv));
shader_set_i("useTexture", is_surface(_text));
object.apply();
draw_sprite_stretched(s_fx_pixel, 0, 0, 0, _dim[0], _dim[1]);
surface_reset_shader();
gpu_set_texfilter(false);
return _outSurf;
return [ _outSurf, object ];
}
}

View file

@ -5,8 +5,8 @@
"isDnD":false,
"name":"node_rm_primitive",
"parent":{
"name":"ray march",
"path":"folders/nodes/data/generator/ray march.yy",
"name":"raymarching",
"path":"folders/nodes/data/3D/raymarching.yy",
},
"resourceType":"GMScript",
"resourceVersion":"2.0",

View file

@ -5,8 +5,8 @@
"isDnD":false,
"name":"node_rm_terrain",
"parent":{
"name":"ray march",
"path":"folders/nodes/data/generator/ray march.yy",
"name":"raymarching",
"path":"folders/nodes/data/3D/raymarching.yy",
},
"resourceType":"GMScript",
"resourceVersion":"2.0",

View file

@ -1,6 +1,9 @@
//Inigo Quilez
//Oh where would I be without you.
#define MAX_SHAPES 16
#define MAX_OP 32
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
@ -18,54 +21,65 @@ uniform sampler2D texture1;
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform float time;
uniform int operations[MAX_OP];
uniform int opLength;
uniform int shape;
uniform vec3 size;
uniform float radius;
uniform float thickness;
uniform float crop;
uniform float angle;
uniform float height;
uniform vec2 radRange;
uniform float sizeUni;
uniform vec3 elongate;
uniform float rounded;
///////////////////////////////////////////////////////////////////
uniform vec3 waveAmp;
uniform vec3 waveInt;
uniform vec3 waveShift;
uniform int shapeAmount;
uniform int shape[MAX_SHAPES] ;
uniform vec3 size[MAX_SHAPES] ;
uniform float radius[MAX_SHAPES] ;
uniform float thickness[MAX_SHAPES] ;
uniform float crop[MAX_SHAPES] ;
uniform float angle[MAX_SHAPES] ;
uniform float height[MAX_SHAPES] ;
uniform vec2 radRange[MAX_SHAPES] ;
uniform float sizeUni[MAX_SHAPES] ;
uniform vec3 elongate[MAX_SHAPES] ;
uniform float rounded[MAX_SHAPES] ;
uniform vec4 corner[MAX_SHAPES] ;
uniform vec2 size2D[MAX_SHAPES] ;
uniform int sides[MAX_SHAPES] ;
uniform int twistAxis;
uniform float twistAmount;
uniform vec3 waveAmp[MAX_SHAPES] ;
uniform vec3 waveInt[MAX_SHAPES] ;
uniform vec3 waveShift[MAX_SHAPES] ;
uniform vec3 position;
uniform vec3 rotation;
uniform float objectScale;
uniform int twistAxis[MAX_SHAPES] ;
uniform float twistAmount[MAX_SHAPES] ;
uniform vec3 position[MAX_SHAPES] ;
uniform vec3 rotation[MAX_SHAPES] ;
uniform float objectScale[MAX_SHAPES] ;
uniform vec3 tileSize[MAX_SHAPES] ;
uniform vec3 tileAmount[MAX_SHAPES] ;
uniform vec4 diffuseColor[MAX_SHAPES] ;
uniform float reflective[MAX_SHAPES] ;
uniform int volumetric[MAX_SHAPES] ;
uniform float volumeDensity[MAX_SHAPES] ;
uniform int useTexture[MAX_SHAPES] ;
uniform float textureScale[MAX_SHAPES] ;
uniform float triplanar[MAX_SHAPES] ;
///////////////////////////////////////////////////////////////////
uniform int ortho;
uniform float fov;
uniform float orthoScale;
uniform vec2 viewRange;
uniform float depthInt;
uniform vec3 tileSize;
uniform vec3 tileAmount;
uniform int drawBg;
uniform vec4 background;
uniform float ambientIntns;
uniform vec3 lightPosition;
uniform vec4 ambient;
uniform float reflective;
uniform int useEnv;
uniform int useTexture;
uniform float textureScale;
uniform float triplanar;
uniform int volumetric;
uniform float volumeDensity;
mat3 rotMatrix, irotMatrix;
@ -152,7 +166,33 @@ mat3 rotMatrix, irotMatrix;
#endregion
#region ////========== Primitives ===========
#region ////======== 2D Primitives ==========
float sdRoundedBox( in vec2 p, in vec2 b, in vec4 r ) {
r.xy = (p.x > 0.0)? r.xy : r.zw;
r.x = (p.y > 0.0)? r.x : r.y;
vec2 q = abs(p) - b + r.x;
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x;
}
float sdRegularPolygon(in vec2 p, in float r, in int n ) {
// these 4 lines can be precomputed for a given shape
float an = 3.141593 / float(n);
vec2 acs = vec2(cos(an), sin(an));
// reduce to first sector
float bn = mod(atan(p.x, p.y), 2.0 * an) - an;
p = length(p) * vec2(cos(bn), abs(sin(bn)));
// line sdf
p -= r * acs;
p.y += clamp( -p.y, 0.0, r * acs.y);
return length(p) * sign(p.x);
}
#endregion
#region ////======== 3D Primitives ==========
float sdPlane( vec3 p, vec3 n, float h ) {
return dot(p,n) + h;
@ -327,35 +367,40 @@ mat3 rotMatrix, irotMatrix;
#region ////============ Modify =============
vec4 opElongate( in vec3 p, in vec3 h ) {
vec3 q = abs(p)-h;
return vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );
vec3 q = abs(p) - h;
return vec4( max(q, 0.0), min(max(q.x, max(q.y, q.z)), 0.0) );
}
vec3 wave(vec3 p) {
p.x += sin(p.y * waveAmp.y + waveShift.x * PI * 2.) * waveInt.x +
sin(p.z * waveAmp.z + waveShift.x * PI * 2.) * waveInt.x;
p.y += sin(p.x * waveAmp.x + waveShift.y * PI * 2.) * waveInt.y +
sin(p.z * waveAmp.z + waveShift.y * PI * 2.) * waveInt.y;
p.z += sin(p.y * waveAmp.y + waveShift.z * PI * 2.) * waveInt.z +
sin(p.x * waveAmp.x + waveShift.z * PI * 2.) * waveInt.z;
float opExtrusion( in vec3 p, in float h, in float df2d ) {
vec2 w = vec2( df2d, abs(p.z) - h );
return min(max(w.x, w.y), 0.0) + length(max(w, 0.0));
}
vec3 wave(int index, vec3 p) {
p.x += sin(p.y * waveAmp[index].y + waveShift[index].x * PI * 2.) * waveInt[index].x +
sin(p.z * waveAmp[index].z + waveShift[index].x * PI * 2.) * waveInt[index].x;
p.y += sin(p.x * waveAmp[index].x + waveShift[index].y * PI * 2.) * waveInt[index].y +
sin(p.z * waveAmp[index].z + waveShift[index].y * PI * 2.) * waveInt[index].y;
p.z += sin(p.y * waveAmp[index].y + waveShift[index].z * PI * 2.) * waveInt[index].z +
sin(p.x * waveAmp[index].x + waveShift[index].z * PI * 2.) * waveInt[index].z;
return p;
}
vec3 twist(vec3 p) {
vec3 twist(int index, vec3 p) {
float c = cos(twistAmount * p[twistAxis]);
float s = sin(twistAmount * p[twistAxis]);
float c = cos(twistAmount[index] * p[twistAxis[index]]);
float s = sin(twistAmount[index] * p[twistAxis[index]]);
mat2 m = mat2(c, -s, s, c);
if(twistAxis == 0) {
if(twistAxis[index] == 0) {
vec2 q = m * p.yz;
return vec3(p.x, q);
} else if(twistAxis == 1) {
} else if(twistAxis[index] == 1) {
vec2 q = m * p.xz;
return vec3(q.x, p.y, q.y);
} else if(twistAxis == 2) {
} else if(twistAxis[index] == 2) {
vec2 q = m * p.xy;
return vec3(q, p.z);
@ -364,6 +409,21 @@ mat3 rotMatrix, irotMatrix;
return p;
}
float opSmoothUnion( float d1, float d2, float k ) {
float h = clamp( 0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0 );
return mix( d2, d1, h ) - k * h * (1.0 - h);
}
float opSmoothSubtraction( float d1, float d2, float k ) {
float h = clamp( 0.5 - 0.5 * (d2 + d1) / k, 0.0, 1.0 );
return mix( d2, -d1, h ) + k * h * (1.0 - h);
}
float opSmoothIntersection( float d1, float d2, float k ) {
float h = clamp( 0.5 - 0.5 * (d2 - d1) / k, 0.0, 1.0 );
return mix( d2, d1, h ) + k * h * (1.0 - h);
}
#endregion
#region ////=========== View Mod ============
@ -371,10 +431,10 @@ mat3 rotMatrix, irotMatrix;
float round(float v) { return fract(v) >= 0.5? ceil(v) : floor(v); }
vec3 round(vec3 v) { return vec3(round(v.x), round(v.y), round(v.z)); }
vec3 tilePosition(vec3 p) {
if(tileAmount == vec3(0.))
return p - tileSize * round(p / tileSize);
return p - tileSize * clamp(round(p / tileSize), -tileAmount, tileAmount);
vec3 tilePosition(int index, vec3 p) {
if(tileAmount[index] == vec3(0.))
return p - tileSize[index] * round(p / tileSize[index]);
return p - tileSize[index] * clamp(round(p / tileSize[index]), -tileAmount[index], tileAmount[index]);
}
#endregion
@ -397,67 +457,81 @@ mat3 rotMatrix, irotMatrix;
////========= Ray Marching ==========
float sceneSDF(vec3 p) {
float sceneSDF(int index, vec3 p) {
float d;
p = wave(p);
mat3 rx = rotateX(rotation[index].x);
mat3 ry = rotateY(rotation[index].y);
mat3 rz = rotateZ(rotation[index].z);
rotMatrix = rx * ry * rz;
irotMatrix = inverse(rotMatrix);
if(tileSize != vec3(0.))
p = tilePosition(p);
p /= objectScale[index];
p -= position[index];
p = irotMatrix * p;
p = twist(p);
p = wave(index, p);
if(tileSize[index] != vec3(0.))
p = tilePosition(index, p);
p = twist(index, p);
vec4 el = vec4(0.);
if(elongate != vec3(0.)) {
el = opElongate(p, elongate);
if(elongate[index] != vec3(0.)) {
el = opElongate(p, elongate[index]);
p = el.xyz;
}
if(shape == 100) d = sdPlane(p, vec3(0., -1., 0.), 0.);
else if(shape == 101) d = sdBox(p, size / 2.);
else if(shape == 102) d = sdBoxFrame(p, size / 2., thickness);
int shp = shape[index];
else if(shape == 200) d = sdSphere(p, radius);
else if(shape == 201) d = sdEllipsoid(p, size / 2.);
else if(shape == 202) d = sdCutSphere(p, radius, crop);
else if(shape == 203) d = sdCutHollowSphere(p, radius, crop, thickness);
else if(shape == 204) d = sdTorus(p, vec2(radius, thickness));
else if(shape == 205) d = sdCappedTorus(p, angle, radius, thickness);
if(shp == 100) d = sdPlane( p, vec3(0., -1., 0.), 0.);
else if(shp == 101) d = sdBox( p, size[index] / 2.);
else if(shp == 102) d = sdBoxFrame( p, size[index] / 2., thickness[index]);
else if(shp == 103) d = opExtrusion( p, thickness[index], sdRoundedBox(p.xy, size2D[index], corner[index]));
else if(shape == 300) d = sdCappedCylinder(p, height, radius);
else if(shape == 301) d = sdCapsule(p, vec3(-height, 0., 0.), vec3(height, 0., 0.), radius);
else if(shape == 302) d = sdCone(p, angle, height);
else if(shape == 303) d = sdCappedCone(p, height, radRange.x, radRange.y);
else if(shape == 304) d = sdRoundCone(p, height, radRange.x, radRange.y);
else if(shape == 305) d = sdSolidAngle(p, angle, radius);
else if(shp == 200) d = sdSphere( p, radius[index]);
else if(shp == 201) d = sdEllipsoid( p, size[index] / 2.);
else if(shp == 202) d = sdCutSphere( p, radius[index], crop[index]);
else if(shp == 203) d = sdCutHollowSphere( p, radius[index], crop[index], thickness[index]);
else if(shp == 204) d = sdTorus( p, vec2(radius[index], thickness[index]));
else if(shp == 205) d = sdCappedTorus( p, angle[index], radius[index], thickness[index]);
else if(shape == 400) d = sdOctahedron(p, sizeUni);
else if(shape == 401) d = sdPyramid(p, sizeUni);
else if(shp == 300) d = sdCappedCylinder( p, height[index], radius[index]);
else if(shp == 301) d = sdCapsule( p, vec3(-height[index], 0., 0.), vec3(height[index], 0., 0.), radius[index]);
else if(shp == 302) d = sdCone( p, angle[index], height[index]);
else if(shp == 303) d = sdCappedCone( p, height[index], radRange[index].x, radRange[index].y);
else if(shp == 304) d = sdRoundCone( p, height[index], radRange[index].x, radRange[index].y);
else if(shp == 305) d = sdSolidAngle( p, angle[index], radius[index]);
else if(shp == 306) d = opExtrusion( p, thickness[index], sdRegularPolygon(p.xy, 0.5, sides[index]));
if(elongate != vec3(0.)) {
else if(shp == 400) d = sdOctahedron( p, sizeUni[index]);
else if(shp == 401) d = sdPyramid( p, sizeUni[index]);
if(elongate[index] != vec3(0.)) {
d += el.w;
}
d -= rounded;
d *= objectScale;
d -= rounded[index];
d *= objectScale[index];
return d;
}
vec3 normal(vec3 p) {
vec3 normal(int index, vec3 p) {
return normalize(vec3(
sceneSDF(vec3(p.x + EPSILON, p.y, p.z)) - sceneSDF(vec3(p.x - EPSILON, p.y, p.z)),
sceneSDF(vec3(p.x, p.y + EPSILON, p.z)) - sceneSDF(vec3(p.x, p.y - EPSILON, p.z)),
sceneSDF(vec3(p.x, p.y, p.z + EPSILON)) - sceneSDF(vec3(p.x, p.y, p.z - EPSILON))
sceneSDF(index, vec3(p.x + EPSILON, p.y, p.z)) - sceneSDF(index, vec3(p.x - EPSILON, p.y, p.z)),
sceneSDF(index, vec3(p.x, p.y + EPSILON, p.z)) - sceneSDF(index, vec3(p.x, p.y - EPSILON, p.z)),
sceneSDF(index, vec3(p.x, p.y, p.z + EPSILON)) - sceneSDF(index, vec3(p.x, p.y, p.z - EPSILON))
));
}
float march(vec3 camera, vec3 direction) {
float march(int index, vec3 camera, vec3 direction) {
float depth = viewRange.x;
for (int i = 0; i < MAX_MARCHING_STEPS; i++) {
float dist = sceneSDF(camera + depth * direction);
float dist = sceneSDF(index, camera + depth * direction);
if (dist < EPSILON)
return depth;
@ -469,16 +543,16 @@ float march(vec3 camera, vec3 direction) {
return viewRange.y;
}
float marchDensity(vec3 camera, vec3 direction) {
float marchDensity(int index, vec3 camera, vec3 direction) {
float st = 1. / float(MAX_MARCHING_STEPS);
float dens = 0.;
float stp = volumeDensity == 0. ? 0. : pow(2., 10. * volumeDensity * 0.5 - 10.);
float stp = volumeDensity[index] == 0. ? 0. : pow(2., 10. * volumeDensity[index] * 0.5 - 10.);
for (int i = 0; i <= MAX_MARCHING_STEPS; i++) {
float depth = mix(viewRange.x, viewRange.y, float(i) * st);
vec3 pos = camera + depth * direction;
float hit = sceneSDF(pos);
float inst = (pos.y + objectScale) / (objectScale * 2.);
float hit = sceneSDF(index, pos);
float inst = (pos.y + objectScale[index]) / (objectScale[index] * 2.);
inst = inst <= 0.? 0. : pow(2., 10. * inst - 10.) * 10.;
if (hit <= 0.) dens += stp;
@ -487,81 +561,170 @@ float marchDensity(vec3 camera, vec3 direction) {
return dens;
}
void main() {
mat3 rx = rotateX(rotation.x);
mat3 ry = rotateY(rotation.y);
mat3 rz = rotateZ(rotation.z);
rotMatrix = rx * ry * rz;
irotMatrix = inverse(rotMatrix);
vec4 scene(int index, out float depth, out vec3 coll, out vec3 norm) {
depth = 0.;
float dz = 1. / tan(radians(fov) / 2.);
vec3 dir = normalize(vec3((v_vTexcoord - .5) * 2., -dz));
vec3 eye = vec3(0., 0., 5.);
dir = normalize(irotMatrix * dir) / objectScale;
eye = irotMatrix * eye;
eye /= objectScale;
eye -= position;
vec4 bg = background;
if(useEnv == 1) {
float edz = 1. / tan(radians(fov * 2.) / 2.);
vec3 edir = normalize(vec3((v_vTexcoord - .5) * 2., -edz));
edir = normalize(irotMatrix * edir) / objectScale;
vec2 envUV = equirectangularUv(edir);
vec4 endC = sampleTexture(0, envUV);
bg = endC;
if(volumetric[index] == 1) {
float _dens = clamp(marchDensity(index, eye, dir), 0., 1.);
return diffuseColor[index] * _dens;
}
gl_FragColor = drawBg == 1? bg : vec4(0.);
depth = march(index, eye, dir);
coll = eye + dir * depth;
norm = normal(index, coll);
if(volumetric == 1) {
float _dens = clamp(marchDensity(eye, dir), 0., 1.);
gl_FragColor = mix(background, ambient, _dens);
return;
}
if(depth > viewRange.y - EPSILON) // Not hitting anything.
return vec4(0.);
float dist = march(eye, dir);
vec3 coll = eye + dir * dist;
vec3 wcoll = irotMatrix * coll;
vec3 norm = normal(coll);
if(dist > viewRange.y - EPSILON) // Not hitting anything.
return;
vec3 c = useTexture == 1? boxmap(1, coll * textureScale, norm, triplanar).rgb * ambient.rgb : ambient.rgb;
vec3 c = useTexture[index] == 1?
boxmap(int(TEXTURE_S) + index, coll * textureScale[index], norm, triplanar[index]).rgb * diffuseColor[index].rgb :
diffuseColor[index].rgb;
///////////////////////////////////////////////////////////
float distNorm = (dist - viewRange.x) / (viewRange.y - viewRange.x);
float distNorm = (depth - viewRange.x) / (viewRange.y - viewRange.x);
distNorm = 1. - distNorm;
distNorm = smoothstep(.0, .3, distNorm);
c = mix(background.rgb, c, mix(1., distNorm, depthInt));
c = mix(c * background.rgb, c, mix(1., distNorm, depthInt));
///////////////////////////////////////////////////////////
vec3 ref = reflect(dir, norm);
if(useEnv == 1) {
vec4 refC = sampleTexture(0, equirectangularUv(ref))
+ sampleTexture(0, equirectangularUv(ref + vec3( 0.01, 0., 0.))) * 0.5
+ sampleTexture(0, equirectangularUv(ref + vec3(-0.01, 0., 0.))) * 0.5
+ sampleTexture(0, equirectangularUv(ref + vec3(0., 0.01, 0.))) * 0.5
+ sampleTexture(0, equirectangularUv(ref + vec3(0., -0.01, 0.))) * 0.5
+ sampleTexture(0, equirectangularUv(ref + vec3(0., 0., 0.01))) * 0.5
+ sampleTexture(0, equirectangularUv(ref + vec3(0., 0., -0.01))) * 0.5;
refC /= 4.;
c = mix(c, c * refC.rgb, reflective);
vec3 ref = reflect(dir, norm);
vec4 refC = sampleTexture(0, equirectangularUv(ref));
c = mix(c, c * refC.rgb, reflective[index]);
}
///////////////////////////////////////////////////////////
vec3 light = normalize(lightPosition);
float lamo = min(1., max(0., dot(norm, light)) + ambientIntns);
c = mix(background.rgb, c, lamo);
c = mix(c * background.rgb, c, lamo);
gl_FragColor = vec4(c, 1.);
return vec4(c, 1.);
}
vec4 sceneBlend(float depth, vec4 color, vec3 norm) {
if(depth > viewRange.y - EPSILON) // Not hitting anything.
return vec4(0.);
vec3 c = color.rgb;
///////////////////////////////////////////////////////////
float distNorm = (depth - viewRange.x) / (viewRange.y - viewRange.x);
distNorm = 1. - distNorm;
distNorm = smoothstep(.0, .3, distNorm);
c = mix(c * background.rgb, c, mix(1., distNorm, depthInt));
vec3 light = normalize(lightPosition);
float lamo = min(1., max(0., dot(norm, light)) + ambientIntns);
c = mix(c * background.rgb, c, lamo);
return vec4(c, 1.);
}
vec4 blend(in vec4 bg, in vec4 fg) {
float al = fg.a + bg.a * (1. - fg.a);
if(al == 0.) return bg;
vec4 res = ((fg * fg.a) + (bg * bg.a * (1. - fg.a))) / al;
res.a = al;
return res;
}
vec4 operate() {
vec4 color[MAX_OP];
vec3 colis[MAX_OP];
vec3 norml[MAX_OP];
float depth[MAX_OP];
int top = 0;
int opr = 0;
float d1, d2, dm, rt;
vec3 n1, n2, cl;
vec4 c1, c2;
float yy = viewRange.y - EPSILON;
for(int i = 0; i < opLength; i++) {
opr = operations[i];
if(opr < 100) {
color[top] = scene(opr, d1, cl, n1);
depth[top] = d1;
colis[top] = cl;
norml[top] = n1;
top++;
} else {
top--;
c1 = color[top];
d1 = depth[top];
n1 = norml[top];
top--;
c2 = color[top];
d2 = depth[top];
n2 = norml[top];
if(opr == 100) {
if(d1 < yy || d2 < yy) {
if(d1 < d2) {
color[top] = c1;
depth[top] = d1;
norml[top] = n1;
} else {
color[top] = c2;
depth[top] = d2;
norml[top] = n2;
}
} else {
color[top] = vec4(0.);
depth[top] = 0.;
norml[top] = vec3(0.);
}
top++;
}
}
}
return color[0];
}
void main() {
vec4 bg = background;
if(useEnv == 1) {
float edz = 1. / tan(radians(fov * 2.) / 2.);
vec3 edir = normalize(vec3((v_vTexcoord - .5) * 2., -edz));
//edir = normalize(irotMatrix * edir) / objectScale[index];
vec2 envUV = equirectangularUv(edir);
vec4 endC = sampleTexture(0, envUV);
bg = endC;
}
vec4 result = drawBg == 1? bg : vec4(0.);
float d;
vec3 c, n;
if(operations[0] == -1)
result = blend(result, scene(0, d, c, n));
else
result = blend(result, operate());
//////////////////////////////////////////////////
gl_FragColor = result;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1,90 @@
{
"$GMSprite":"",
"%Name":"s_node_rm_combine",
"bboxMode":0,
"bbox_bottom":62,
"bbox_left":2,
"bbox_right":60,
"bbox_top":3,
"collisionKind":1,
"collisionTolerance":0,
"DynamicTexturePage":false,
"edgeFiltering":false,
"For3D":false,
"frames":[
{"$GMSpriteFrame":"","%Name":"f98e82e8-b6b4-45a9-ba89-baaf12d9ca96","name":"f98e82e8-b6b4-45a9-ba89-baaf12d9ca96","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
],
"gridX":0,
"gridY":0,
"height":64,
"HTile":false,
"layers":[
{"$GMImageLayer":"","%Name":"37957189-91ab-49cb-b8e0-ce22fdb9b0c2","blendMode":0,"displayName":"default","isLocked":false,"name":"37957189-91ab-49cb-b8e0-ce22fdb9b0c2","opacity":100.0,"resourceType":"GMImageLayer","resourceVersion":"2.0","visible":true,},
],
"name":"s_node_rm_combine",
"nineSlice":null,
"origin":4,
"parent":{
"name":"3D",
"path":"folders/nodes/icons/3D.yy",
},
"preMultiplyAlpha":false,
"resourceType":"GMSprite",
"resourceVersion":"2.0",
"sequence":{
"$GMSequence":"",
"%Name":"s_node_rm_combine",
"autoRecord":true,
"backdropHeight":768,
"backdropImageOpacity":0.5,
"backdropImagePath":"",
"backdropWidth":1366,
"backdropXOffset":0.0,
"backdropYOffset":0.0,
"events":{
"$KeyframeStore<MessageEventKeyframe>":"",
"Keyframes":[],
"resourceType":"KeyframeStore<MessageEventKeyframe>",
"resourceVersion":"2.0",
},
"eventStubScript":null,
"eventToFunction":{},
"length":1.0,
"lockOrigin":false,
"moments":{
"$KeyframeStore<MomentsEventKeyframe>":"",
"Keyframes":[],
"resourceType":"KeyframeStore<MomentsEventKeyframe>",
"resourceVersion":"2.0",
},
"name":"s_node_rm_combine",
"playback":1,
"playbackSpeed":30.0,
"playbackSpeedType":0,
"resourceType":"GMSequence",
"resourceVersion":"2.0",
"showBackdrop":true,
"showBackdropImage":false,
"timeUnits":1,
"tracks":[
{"$GMSpriteFramesTrack":"","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"$KeyframeStore<SpriteFrameKeyframe>":"","Keyframes":[
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"f98e82e8-b6b4-45a9-ba89-baaf12d9ca96","path":"sprites/s_node_rm_combine/s_node_rm_combine.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"4e0e75a6-eac6-4ea3-bcb4-b6500b531b73","IsCreationKey":false,"Key":0.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
],"resourceType":"KeyframeStore<SpriteFrameKeyframe>","resourceVersion":"2.0",},"modifiers":[],"name":"frames","resourceType":"GMSpriteFramesTrack","resourceVersion":"2.0","spriteId":null,"trackColour":0,"tracks":[],"traits":0,},
],
"visibleRange":null,
"volume":1.0,
"xorigin":32,
"yorigin":32,
},
"swatchColours":null,
"swfPrecision":0.5,
"textureGroupId":{
"name":"Default",
"path":"texturegroups/Default",
},
"type":0,
"VTile":false,
"width":64,
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

View file

@ -15,6 +15,7 @@
{"$GMSpriteFrame":"","%Name":"4bb74abc-c433-4d95-90b8-6d432203f2cd","name":"4bb74abc-c433-4d95-90b8-6d432203f2cd","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"788d0a63-e4df-49ea-b9e1-498a0cef9940","name":"788d0a63-e4df-49ea-b9e1-498a0cef9940","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"d63e2d22-1c1d-4d1e-9894-773d9bcc75bf","name":"d63e2d22-1c1d-4d1e-9894-773d9bcc75bf","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"2ea21084-4785-418a-a413-2b896df41ff7","name":"2ea21084-4785-418a-a413-2b896df41ff7","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"f8ceda58-3651-4496-8acc-d0031209c85f","name":"f8ceda58-3651-4496-8acc-d0031209c85f","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"a67f4783-975c-4385-800c-bda14bc788aa","name":"a67f4783-975c-4385-800c-bda14bc788aa","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"fbeb2617-f75b-4d4d-8652-159e2cd0677e","name":"fbeb2617-f75b-4d4d-8652-159e2cd0677e","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
@ -22,6 +23,7 @@
{"$GMSpriteFrame":"","%Name":"a9144d25-0a29-4a41-af37-91fa66dcfbd8","name":"a9144d25-0a29-4a41-af37-91fa66dcfbd8","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"55e17775-8c99-4c34-afba-32ff17aea0cd","name":"55e17775-8c99-4c34-afba-32ff17aea0cd","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"91e98279-4857-4edb-ad31-965ed879434f","name":"91e98279-4857-4edb-ad31-965ed879434f","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"193adda1-e9c3-42e9-88f0-4335a4a2885f","name":"193adda1-e9c3-42e9-88f0-4335a4a2885f","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"77a94bee-9795-42c2-b8d8-fa8feb667cc0","name":"77a94bee-9795-42c2-b8d8-fa8feb667cc0","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"5cc8219a-02e5-4b49-89f9-41ee24b035bb","name":"5cc8219a-02e5-4b49-89f9-41ee24b035bb","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"8f00908e-92e2-474b-9d0c-8b2fb8dba4ff","name":"8f00908e-92e2-474b-9d0c-8b2fb8dba4ff","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
@ -65,7 +67,7 @@
},
"eventStubScript":null,
"eventToFunction":{},
"length":17.0,
"length":19.0,
"lockOrigin":false,
"moments":{
"$KeyframeStore<MomentsEventKeyframe>":"",
@ -93,48 +95,54 @@
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"d63e2d22-1c1d-4d1e-9894-773d9bcc75bf","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"01d746c2-9f2e-4827-bdca-8d666a0bdafb","IsCreationKey":false,"Key":2.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"2ea21084-4785-418a-a413-2b896df41ff7","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"966893bb-f205-4359-b56a-cfeb6af18996","IsCreationKey":false,"Key":3.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"f8ceda58-3651-4496-8acc-d0031209c85f","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"cd773a0c-d83e-4137-8641-ce60b984a397","IsCreationKey":false,"Key":3.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"cd773a0c-d83e-4137-8641-ce60b984a397","IsCreationKey":false,"Key":4.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"a67f4783-975c-4385-800c-bda14bc788aa","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"973d9998-69d3-404a-9cb8-b58045f5c85e","IsCreationKey":false,"Key":4.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"973d9998-69d3-404a-9cb8-b58045f5c85e","IsCreationKey":false,"Key":5.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"fbeb2617-f75b-4d4d-8652-159e2cd0677e","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"065ed05a-9605-4af3-b699-411314780dd9","IsCreationKey":false,"Key":5.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"065ed05a-9605-4af3-b699-411314780dd9","IsCreationKey":false,"Key":6.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"3c36db85-d4c1-4eac-8539-0152ee45e89c","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"8942bd33-2f9c-4364-b560-379aea9087e1","IsCreationKey":false,"Key":6.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"8942bd33-2f9c-4364-b560-379aea9087e1","IsCreationKey":false,"Key":7.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"a9144d25-0a29-4a41-af37-91fa66dcfbd8","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"dbe39012-01eb-417f-b8d9-de7de7e3cc79","IsCreationKey":false,"Key":7.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"dbe39012-01eb-417f-b8d9-de7de7e3cc79","IsCreationKey":false,"Key":8.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"55e17775-8c99-4c34-afba-32ff17aea0cd","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"5a803cfc-b354-4e3c-ae22-732d2c0831b0","IsCreationKey":false,"Key":8.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"5a803cfc-b354-4e3c-ae22-732d2c0831b0","IsCreationKey":false,"Key":9.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"91e98279-4857-4edb-ad31-965ed879434f","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"128c27fa-31bf-49b4-9f01-8211419db89a","IsCreationKey":false,"Key":9.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"128c27fa-31bf-49b4-9f01-8211419db89a","IsCreationKey":false,"Key":10.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"193adda1-e9c3-42e9-88f0-4335a4a2885f","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"43c020f4-7a49-45b8-8119-4262664f7f7f","IsCreationKey":false,"Key":11.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"77a94bee-9795-42c2-b8d8-fa8feb667cc0","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"802c6cbf-5e03-463e-8a6f-285fb6a9b498","IsCreationKey":false,"Key":10.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"802c6cbf-5e03-463e-8a6f-285fb6a9b498","IsCreationKey":false,"Key":12.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"5cc8219a-02e5-4b49-89f9-41ee24b035bb","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"a7b050d2-5107-422c-bc16-c73bd17414bd","IsCreationKey":false,"Key":11.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"a7b050d2-5107-422c-bc16-c73bd17414bd","IsCreationKey":false,"Key":13.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"8f00908e-92e2-474b-9d0c-8b2fb8dba4ff","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"b41afe65-df8a-4c93-a239-da4965713fba","IsCreationKey":false,"Key":12.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"b41afe65-df8a-4c93-a239-da4965713fba","IsCreationKey":false,"Key":14.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"16bfc80e-e29e-4d4e-85bc-db11d8be1e35","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"cf14bd6d-4ac0-466e-ad27-4af436999f18","IsCreationKey":false,"Key":13.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"cf14bd6d-4ac0-466e-ad27-4af436999f18","IsCreationKey":false,"Key":15.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"53ff437f-736a-41e3-b500-bc9e840439d0","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"36d7040b-a1cc-4ce4-935a-805894d9d303","IsCreationKey":false,"Key":14.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"36d7040b-a1cc-4ce4-935a-805894d9d303","IsCreationKey":false,"Key":16.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"0da22937-fff4-452f-a8d6-3e8b57726d6e","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"b6642d24-2c86-4b2b-bceb-5d9f6a4c287c","IsCreationKey":false,"Key":15.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"b6642d24-2c86-4b2b-bceb-5d9f6a4c287c","IsCreationKey":false,"Key":17.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"1c600a42-babc-45aa-ba0b-00dad6ef1e04","path":"sprites/s_node_shape_3d/s_node_shape_3d.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"14b14ac0-8cf2-4f3f-aa4f-441b9aec23d8","IsCreationKey":false,"Key":16.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
},"Disabled":false,"id":"14b14ac0-8cf2-4f3f-aa4f-441b9aec23d8","IsCreationKey":false,"Key":18.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
],"resourceType":"KeyframeStore<SpriteFrameKeyframe>","resourceVersion":"2.0",},"modifiers":[],"name":"frames","resourceType":"GMSpriteFramesTrack","resourceVersion":"2.0","spriteId":null,"trackColour":0,"tracks":[],"traits":0,},
],
"visibleRange":null,