From 1790d564ca425bc7dae02d640f4c3899fd44d0a6 Mon Sep 17 00:00:00 2001 From: Tanasart Date: Sun, 20 Oct 2024 16:47:29 +0700 Subject: [PATCH] New Sky generator node. --- PixelComposer.resource_order | 3 + PixelComposer.yyp | 3 + scripts/node_registry/node_registry.gml | 2 +- scripts/node_sky/node_sky.gml | 92 +++- shaders/sh_sky_hosek/sh_sky_hosek.fsh | 401 ++++++++++++++++++ shaders/sh_sky_hosek/sh_sky_hosek.vsh | 19 + shaders/sh_sky_hosek/sh_sky_hosek.yy | 12 + shaders/sh_sky_preetham/sh_sky_preetham.fsh | 38 +- .../sh_sky_scattering/sh_sky_scattering.fsh | 246 +++++++++++ .../sh_sky_scattering/sh_sky_scattering.vsh | 19 + .../sh_sky_scattering/sh_sky_scattering.yy | 12 + .../68373dee-c8d3-42f8-a753-ddf0f15676ed.png | Bin 0 -> 2803 bytes .../f370aa54-fd4b-4081-bb69-366f6a87e8e6.png | Bin 0 -> 2803 bytes sprites/s_node_sky/s_node_sky.yy | 90 ++++ 14 files changed, 907 insertions(+), 30 deletions(-) create mode 100644 shaders/sh_sky_hosek/sh_sky_hosek.fsh create mode 100644 shaders/sh_sky_hosek/sh_sky_hosek.vsh create mode 100644 shaders/sh_sky_hosek/sh_sky_hosek.yy create mode 100644 shaders/sh_sky_scattering/sh_sky_scattering.fsh create mode 100644 shaders/sh_sky_scattering/sh_sky_scattering.vsh create mode 100644 shaders/sh_sky_scattering/sh_sky_scattering.yy create mode 100644 sprites/s_node_sky/68373dee-c8d3-42f8-a753-ddf0f15676ed.png create mode 100644 sprites/s_node_sky/layers/68373dee-c8d3-42f8-a753-ddf0f15676ed/f370aa54-fd4b-4081-bb69-366f6a87e8e6.png create mode 100644 sprites/s_node_sky/s_node_sky.yy diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index c3480ea5f..03b97139d 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -1744,6 +1744,8 @@ {"name":"sh_shape_map_polygon","order":15,"path":"shaders/sh_shape_map_polygon/sh_shape_map_polygon.yy",}, {"name":"sh_simplex","order":16,"path":"shaders/sh_simplex/sh_simplex.yy",}, {"name":"sh_skew","order":6,"path":"shaders/sh_skew/sh_skew.yy",}, + {"name":"sh_sky_hosek","order":2,"path":"shaders/sh_sky_hosek/sh_sky_hosek.yy",}, + {"name":"sh_sky_scattering","order":1,"path":"shaders/sh_sky_scattering/sh_sky_scattering.yy",}, {"name":"sh_slice_spritesheet_empty_scan","order":6,"path":"shaders/sh_slice_spritesheet_empty_scan/sh_slice_spritesheet_empty_scan.yy",}, {"name":"sh_smear","order":13,"path":"shaders/sh_smear/sh_smear.yy",}, {"name":"sh_solid","order":5,"path":"shaders/sh_solid/sh_solid.yy",}, @@ -2504,6 +2506,7 @@ {"name":"s_node_shard","order":33,"path":"sprites/s_node_shard/s_node_shard.yy",}, {"name":"s_node_shell_excecute","order":33,"path":"sprites/s_node_shell_excecute/s_node_shell_excecute.yy",}, {"name":"s_node_skew","order":11,"path":"sprites/s_node_skew/s_node_skew.yy",}, + {"name":"s_node_sky","order":57,"path":"sprites/s_node_sky/s_node_sky.yy",}, {"name":"s_node_slider","order":4,"path":"sprites/s_node_slider/s_node_slider.yy",}, {"name":"s_node_smear","order":8,"path":"sprites/s_node_smear/s_node_smear.yy",}, {"name":"s_node_smokeSim_add_collider","order":6,"path":"sprites/s_node_smokeSim_add_collider/s_node_smokeSim_add_collider.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index abfc1014a..c04de880d 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -2440,7 +2440,9 @@ {"id":{"name":"sh_shape","path":"shaders/sh_shape/sh_shape.yy",},}, {"id":{"name":"sh_simplex","path":"shaders/sh_simplex/sh_simplex.yy",},}, {"id":{"name":"sh_skew","path":"shaders/sh_skew/sh_skew.yy",},}, + {"id":{"name":"sh_sky_hosek","path":"shaders/sh_sky_hosek/sh_sky_hosek.yy",},}, {"id":{"name":"sh_sky_preetham","path":"shaders/sh_sky_preetham/sh_sky_preetham.yy",},}, + {"id":{"name":"sh_sky_scattering","path":"shaders/sh_sky_scattering/sh_sky_scattering.yy",},}, {"id":{"name":"sh_slice_spritesheet_empty_scan","path":"shaders/sh_slice_spritesheet_empty_scan/sh_slice_spritesheet_empty_scan.yy",},}, {"id":{"name":"sh_smear","path":"shaders/sh_smear/sh_smear.yy",},}, {"id":{"name":"sh_solid","path":"shaders/sh_solid/sh_solid.yy",},}, @@ -3247,6 +3249,7 @@ {"id":{"name":"s_node_shard","path":"sprites/s_node_shard/s_node_shard.yy",},}, {"id":{"name":"s_node_shell_excecute","path":"sprites/s_node_shell_excecute/s_node_shell_excecute.yy",},}, {"id":{"name":"s_node_skew","path":"sprites/s_node_skew/s_node_skew.yy",},}, + {"id":{"name":"s_node_sky","path":"sprites/s_node_sky/s_node_sky.yy",},}, {"id":{"name":"s_node_slider","path":"sprites/s_node_slider/s_node_slider.yy",},}, {"id":{"name":"s_node_smear","path":"sprites/s_node_smear/s_node_smear.yy",},}, {"id":{"name":"s_node_smokeSim_add_collider","path":"sprites/s_node_smokeSim_add_collider/s_node_smokeSim_add_collider.yy",},}, diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 3a1d4b2be..494c2a84c 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -752,7 +752,7 @@ function __initNodes() { addNodeObject(generator, "Solid", s_node_solid, "Node_Solid", [1, Node_Solid],, "Create image of a single color."); addNodeObject(generator, "Draw Gradient", s_node_gradient, "Node_Gradient", [1, Node_Gradient],, "Create image from gradient."); addNodeObject(generator, "Draw 4 Points Gradient", s_node_gradient_4points, "Node_Gradient_Points", [1, Node_Gradient_Points],, "Create image from 4 color points."); - /**/ addNodeObject(generator, "Sky", s_node_gradient_4points, "Node_Sky", [1, Node_Sky],, "Generate sky texture using different model."); + addNodeObject(generator, "Sky", s_node_sky, "Node_Sky", [1, Node_Sky],, "Generate sky texture using different model."); ds_list_add(generator, "Drawer"); addNodeObject(generator, "Draw Line", s_node_line, "Node_Line", [1, Node_Line],, "Draw line on an image. Connect path data to it to draw line from path."); diff --git a/scripts/node_sky/node_sky.gml b/scripts/node_sky/node_sky.gml index 959a0b259..0a076f5d6 100644 --- a/scripts/node_sky/node_sky.gml +++ b/scripts/node_sky/node_sky.gml @@ -3,25 +3,32 @@ function Node_Sky(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) const newInput(0, nodeValue_Dimension(self)); - newInput(1, nodeValue_Enum_Scroll("Model", self, 0, [ "Preetham" ])); + newInput(1, nodeValue_Vec2("Offset", self, [ 0, 0 ])); - newInput(2, nodeValue_Float("Turbidity", self, 2)); + newInput(2, nodeValue_Vec2("Scale", self, [ 1, 1 ])); - newInput(3, nodeValue_Float("Azimuth", self, 0)) - .setDisplay(VALUE_DISPLAY.slider, { range: [ -180, 180, 1 ] }); + newInput(3, nodeValue_Enum_Scroll("Model", self, 0, [ "Preetham", "Basic scattering", "Hosek" ])); - newInput(4, nodeValue_Float("Inclination", self, 0)) - .setDisplay(VALUE_DISPLAY.slider, { range: [ -180, 180, 1 ] }); + newInput(4, nodeValue_Float("Turbidity", self, 2)); - newInput(5, nodeValue_Vec2("Scale", self, [ 1, 1 ])); + newInput(5, nodeValue_Vec2("Sun", self, [ .5, .5 ])) + .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); - newInput(6, nodeValue_Vec2("Offset", self, [ 0, 0 ])); + newInput(6, nodeValue_Float("Sun radius", self, 500)); + + newInput(7, nodeValue_Float("Sun radiance", self, 20)); + + newInput(8, nodeValue_Float("Albedo", self, 1)); + + newInput(9, nodeValue_Enum_Scroll("Coordinate", self, 0, [ "Rectangular", "Polar" ])); newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone)); input_display_list = [ 0, - ["Transform", false], 6, 5, - ["Sky", false], 1, 2, 3, 4, + // ["Transform", false], 1, 2, + ["Sky", false], 3, 4, 8, + ["Sun", false], 5, 6, 7, + //["Render", false], 9, ]; attribute_surface_depth(); @@ -29,30 +36,73 @@ function Node_Sky(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) const static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { var _hov = false; - var hv = inputs[6].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); _hov |= hv; + var hv = inputs[5].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); _hov |= hv; return _hov; } static processData = function(_outSurf, _data, _output_index, _array_index) { var _dim = _data[0]; - var _mod = _data[1]; - var _tur = _data[2]; - var _azi = _data[3]; - var _inc = _data[4]; - var _sca = _data[5]; - var _pos = _data[6]; + var _pos = _data[1]; + var _sca = _data[2]; + + var _mod = _data[3]; + var _tur = _data[4]; + var _sun = _data[5]; + var _sunRad = _data[6]; + var _sunRdd = _data[7]; + var _alb = _data[8]; + var _map = _data[9]; if(_mod == 0) { + inputs[4].setVisible( true); + inputs[6].setVisible(false); + inputs[7].setVisible(false); + inputs[8].setVisible(false); + surface_set_shader(_outSurf, sh_sky_preetham); DRAW_CLEAR shader_set_2("dimension", _dim); - shader_set_2("position", _pos); - shader_set_2("scale", _sca); + shader_set_2("sunPosition", _sun); shader_set_f("turbidity", _tur); - shader_set_f("azimuth", degtorad(_azi)); - shader_set_f("inclination", degtorad(_inc)); + shader_set_i("mapping", _map); + + draw_empty(); + surface_reset_shader(); + + } else if(_mod == 1) { + inputs[4].setVisible(false); + inputs[6].setVisible( true); + inputs[7].setVisible( true); + inputs[8].setVisible(false); + + surface_set_shader(_outSurf, sh_sky_scattering); + DRAW_CLEAR + + shader_set_2("dimension", _dim); + shader_set_2("sunPosition", _sun); + shader_set_f("sunRadius", _sunRad); + shader_set_f("sunRadiance", _sunRdd); + shader_set_i("mapping", _map); + + draw_empty(); + surface_reset_shader(); + + } else if(_mod == 2) { + inputs[4].setVisible(false); + inputs[6].setVisible(false); + inputs[7].setVisible(false); + inputs[8].setVisible(false); + + surface_set_shader(_outSurf, sh_sky_hosek); + DRAW_CLEAR + + shader_set_2("dimension", _dim); + shader_set_2("sunPosition", _sun); + shader_set_f("turbidity", 3); + shader_set_f("albedo", 1); + shader_set_i("mapping", _map); draw_empty(); surface_reset_shader(); diff --git a/shaders/sh_sky_hosek/sh_sky_hosek.fsh b/shaders/sh_sky_hosek/sh_sky_hosek.fsh new file mode 100644 index 000000000..786f791cb --- /dev/null +++ b/shaders/sh_sky_hosek/sh_sky_hosek.fsh @@ -0,0 +1,401 @@ +// Hosek-Wilkie Skylight Model +// By pajunen +// https://www.shadertoy.com/view/wslfD7 + +/* +This source is published under the following 3-clause BSD license. + +Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * None of the names of the contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +// Implementation of 2012 Hosek-Wilkie skylight model +// Ground albedo and turbidity are baked into the lookup tables +#define ALBEDO 1 +#define TURBIDITY 3 + +#define PI 3.1415926535897932384626433832795 +#define CIE_X 0 +#define CIE_Y 1 +#define CIE_Z 2 + +uniform vec2 dimension; +uniform int mapping; + +uniform float albedo; +uniform float turbidity; +uniform vec2 sunPosition; + +float kHosekCoeffsX[54]; +float kHosekCoeffsY[54]; +float kHosekCoeffsZ[54]; + +float kHosekRadX[6]; +float kHosekRadY[6]; +float kHosekRadZ[6]; + +void init() { + kHosekCoeffsX[ 0] = -1.171419; + kHosekCoeffsX[ 1] = -0.242975; + kHosekCoeffsX[ 2] = -8.991334; + kHosekCoeffsX[ 3] = 9.571216; + kHosekCoeffsX[ 4] = -0.027729; + kHosekCoeffsX[ 5] = 0.668826; + kHosekCoeffsX[ 6] = 0.076835; + kHosekCoeffsX[ 7] = 3.785611; + kHosekCoeffsX[ 8] = 0.634764; + kHosekCoeffsX[ 9] = -1.228554; + kHosekCoeffsX[10] = -0.291756; + kHosekCoeffsX[11] = 2.753986; + kHosekCoeffsX[12] = -2.491780; + kHosekCoeffsX[13] = -0.046634; + kHosekCoeffsX[14] = 0.311830; + kHosekCoeffsX[15] = 0.075465; + kHosekCoeffsX[16] = 4.463096; + kHosekCoeffsX[17] = 0.595507; + kHosekCoeffsX[18] = -1.093124; + kHosekCoeffsX[19] = -0.244777; + kHosekCoeffsX[20] = 0.909741; + kHosekCoeffsX[21] = 0.544830; + kHosekCoeffsX[22] = -0.295782; + kHosekCoeffsX[23] = 2.024167; + kHosekCoeffsX[24] = -0.000515; + kHosekCoeffsX[25] = -1.069081; + kHosekCoeffsX[26] = 0.936956; + kHosekCoeffsX[27] = -1.056994; + kHosekCoeffsX[28] = 0.015695; + kHosekCoeffsX[29] = -0.821749; + kHosekCoeffsX[30] = 1.870818; + kHosekCoeffsX[31] = 0.706193; + kHosekCoeffsX[32] = -1.483928; + kHosekCoeffsX[33] = 0.597821; + kHosekCoeffsX[34] = 6.864902; + kHosekCoeffsX[35] = 0.367333; + kHosekCoeffsX[36] = -1.054871; + kHosekCoeffsX[37] = -0.275813; + kHosekCoeffsX[38] = 2.712807; + kHosekCoeffsX[39] = -5.950110; + kHosekCoeffsX[40] = -6.554039; + kHosekCoeffsX[41] = 2.447523; + kHosekCoeffsX[42] = -0.189517; + kHosekCoeffsX[43] = -1.454292; + kHosekCoeffsX[44] = 0.913174; + kHosekCoeffsX[45] = -1.100218; + kHosekCoeffsX[46] = -0.174624; + kHosekCoeffsX[47] = 1.438505; + kHosekCoeffsX[48] = 11.154810; + kHosekCoeffsX[49] = -3.266076; + kHosekCoeffsX[50] = -0.883736; + kHosekCoeffsX[51] = 0.197010; + kHosekCoeffsX[52] = 1.991595; + kHosekCoeffsX[53] = 0.590782; + + kHosekCoeffsY[ 0] = -1.185983; + kHosekCoeffsY[ 1] = -0.258118; + kHosekCoeffsY[ 2] = -7.761056; + kHosekCoeffsY[ 3] = 8.317053; + kHosekCoeffsY[ 4] = -0.033518; + kHosekCoeffsY[ 5] = 0.667667; + kHosekCoeffsY[ 6] = 0.059417; + kHosekCoeffsY[ 7] = 3.820727; + kHosekCoeffsY[ 8] = 0.632403; + kHosekCoeffsY[ 9] = -1.268591; + kHosekCoeffsY[10] = -0.339807; + kHosekCoeffsY[11] = 2.348503; + kHosekCoeffsY[12] = -2.023779; + kHosekCoeffsY[13] = -0.053685; + kHosekCoeffsY[14] = 0.108328; + kHosekCoeffsY[15] = 0.084029; + kHosekCoeffsY[16] = 3.910254; + kHosekCoeffsY[17] = 0.557748; + kHosekCoeffsY[18] = -1.071353; + kHosekCoeffsY[19] = -0.199246; + kHosekCoeffsY[20] = 0.787839; + kHosekCoeffsY[21] = 0.197470; + kHosekCoeffsY[22] = -0.303306; + kHosekCoeffsY[23] = 2.335298; + kHosekCoeffsY[24] = -0.082053; + kHosekCoeffsY[25] = 0.795445; + kHosekCoeffsY[26] = 0.997231; + kHosekCoeffsY[27] = -1.089513; + kHosekCoeffsY[28] = -0.031044; + kHosekCoeffsY[29] = -0.599575; + kHosekCoeffsY[30] = 2.330281; + kHosekCoeffsY[31] = 0.658194; + kHosekCoeffsY[32] = -1.821467; + kHosekCoeffsY[33] = 0.667997; + kHosekCoeffsY[34] = 5.090195; + kHosekCoeffsY[35] = 0.312516; + kHosekCoeffsY[36] = -1.040214; + kHosekCoeffsY[37] = -0.257093; + kHosekCoeffsY[38] = 2.660489; + kHosekCoeffsY[39] = -6.506045; + kHosekCoeffsY[40] = -7.053586; + kHosekCoeffsY[41] = 2.763153; + kHosekCoeffsY[42] = -0.243363; + kHosekCoeffsY[43] = -0.764818; + kHosekCoeffsY[44] = 0.945294; + kHosekCoeffsY[45] = -1.116052; + kHosekCoeffsY[46] = -0.183199; + kHosekCoeffsY[47] = 1.457694; + kHosekCoeffsY[48] = 11.636080; + kHosekCoeffsY[49] = -3.216426; + kHosekCoeffsY[50] = -1.045594; + kHosekCoeffsY[51] = 0.228500; + kHosekCoeffsY[52] = 1.817407; + kHosekCoeffsY[53] = 0.581040; + + kHosekCoeffsZ[ 0] = -1.354183; + kHosekCoeffsZ[ 1] = -0.513062; + kHosekCoeffsZ[ 2] = -42.192680; + kHosekCoeffsZ[ 3] = 42.717720; + kHosekCoeffsZ[ 4] = -0.005365; + kHosekCoeffsZ[ 5] = 0.413674; + kHosekCoeffsZ[ 6] = 0.012352; + kHosekCoeffsZ[ 7] = 2.520122; + kHosekCoeffsZ[ 8] = 0.518727; + kHosekCoeffsZ[ 9] = -1.741434; + kHosekCoeffsZ[10] = -0.958976; + kHosekCoeffsZ[11] = -8.230339; + kHosekCoeffsZ[12] = 9.296799; + kHosekCoeffsZ[13] = -0.009600; + kHosekCoeffsZ[14] = 0.499497; + kHosekCoeffsZ[15] = 0.029555; + kHosekCoeffsZ[16] = 0.366710; + kHosekCoeffsZ[17] = 0.352700; + kHosekCoeffsZ[18] = -0.691735; + kHosekCoeffsZ[19] = 0.215489; + kHosekCoeffsZ[20] = -0.876026; + kHosekCoeffsZ[21] = 0.233412; + kHosekCoeffsZ[22] = -0.019096; + kHosekCoeffsZ[23] = 0.474803; + kHosekCoeffsZ[24] = -0.113851; + kHosekCoeffsZ[25] = 6.515360; + kHosekCoeffsZ[26] = 1.225097; + kHosekCoeffsZ[27] = -1.293189; + kHosekCoeffsZ[28] = -0.421870; + kHosekCoeffsZ[29] = 1.620952; + kHosekCoeffsZ[30] = -0.785860; + kHosekCoeffsZ[31] = -0.037694; + kHosekCoeffsZ[32] = 0.663679; + kHosekCoeffsZ[33] = 0.336494; + kHosekCoeffsZ[34] = -0.534102; + kHosekCoeffsZ[35] = 0.212835; + kHosekCoeffsZ[36] = -0.973552; + kHosekCoeffsZ[37] = -0.132549; + kHosekCoeffsZ[38] = 1.007517; + kHosekCoeffsZ[39] = 0.259826; + kHosekCoeffsZ[40] = 0.067622; + kHosekCoeffsZ[41] = 0.001421; + kHosekCoeffsZ[42] = -0.069160; + kHosekCoeffsZ[43] = 3.185897; + kHosekCoeffsZ[44] = 0.864196; + kHosekCoeffsZ[45] = -1.094800; + kHosekCoeffsZ[46] = -0.196206; + kHosekCoeffsZ[47] = 0.575559; + kHosekCoeffsZ[48] = 0.290626; + kHosekCoeffsZ[49] = 0.262575; + kHosekCoeffsZ[50] = 0.764405; + kHosekCoeffsZ[51] = 0.134749; + kHosekCoeffsZ[52] = 2.677126; + kHosekCoeffsZ[53] = 0.646546; + + kHosekRadX[0] = 1.468395; + kHosekRadX[1] = 2.211970; + kHosekRadX[2] = -2.845869; + kHosekRadX[3] = 20.750270; + kHosekRadX[4] = 15.248220; + kHosekRadX[5] = 19.376220; + + kHosekRadY[0] = 1.516536; + kHosekRadY[1] = 2.438729; + kHosekRadY[2] = -3.624121; + kHosekRadY[3] = 22.986210; + kHosekRadY[4] = 15.997820; + kHosekRadY[5] = 20.700270; + + kHosekRadZ[0] = 1.234428; + kHosekRadZ[1] = 2.289628; + kHosekRadZ[2] = -3.404699; + kHosekRadZ[3] = 14.994360; + kHosekRadZ[4] = 34.683900; + kHosekRadZ[5] = 30.848420; +} + +float sample_coeff(int channel, int albedo, int turbidity, int quintic_coeff, int coeff) { + // int index = 540 * albedo + 54 * turbidity + 9 * quintic_coeff + coeff; + int index = 9 * quintic_coeff + coeff; + if (channel == CIE_X) return kHosekCoeffsX[index]; + if (channel == CIE_Y) return kHosekCoeffsY[index]; + if (channel == CIE_Z) return kHosekCoeffsZ[index]; + return 0.; +} + +float sample_radiance(int channel, int albedo, int turbidity, int quintic_coeff) { + //int index = 60 * albedo + 6 * turbidity + quintic_coeff; + int index = quintic_coeff; + if (channel == CIE_X) return kHosekRadX[index]; + if (channel == CIE_Y) return kHosekRadY[index]; + if (channel == CIE_Z) return kHosekRadZ[index]; + return 0.; +} + +float eval_quintic_bezier(in float[6] control_points, float t) { + float t2 = t * t; + float t3 = t2 * t; + float t4 = t3 * t; + float t5 = t4 * t; + + float t_inv = 1.0 - t; + float t_inv2 = t_inv * t_inv; + float t_inv3 = t_inv2 * t_inv; + float t_inv4 = t_inv3 * t_inv; + float t_inv5 = t_inv4 * t_inv; + + return ( + control_points[0] * t_inv5 + + control_points[1] * 5.0 * t * t_inv4 + + control_points[2] * 10.0 * t2 * t_inv3 + + control_points[3] * 10.0 * t3 * t_inv2 + + control_points[4] * 5.0 * t4 * t_inv + + control_points[5] * t5 + ); +} + +float transform_sun_zenith(float sun_zenith) { + float elevation = PI / 2.0 - sun_zenith; + return pow(elevation / (PI / 2.0), 0.333333); +} + +void get_control_points(int channel, int albedo, int turbidity, int coeff, out float[6] control_points) { + for (int i = 0; i < 6; ++i) control_points[i] = sample_coeff(channel, albedo, turbidity, i, coeff); +} + +void get_control_points_radiance(int channel, int albedo, int turbidity, out float[6] control_points) { + for (int i = 0; i < 6; ++i) control_points[i] = sample_radiance(channel, albedo, turbidity, i); +} + +void get_coeffs(int channel, int albedo, int turbidity, float sun_zenith, out float[9] coeffs) { + float t = transform_sun_zenith(sun_zenith); + for (int i = 0; i < 9; ++i) { + float control_points[6]; + get_control_points(channel, albedo, turbidity, i, control_points); + coeffs[i] = eval_quintic_bezier(control_points, t); + } +} + +vec3 mean_spectral_radiance(int albedo, int turbidity, float sun_zenith) { + vec3 spectral_radiance; + for (int i = 0; i < 3; ++i) { + float control_points[6]; + get_control_points_radiance(i, albedo, turbidity, control_points); + float t = transform_sun_zenith(sun_zenith); + spectral_radiance[i] = eval_quintic_bezier(control_points, t); + } + return spectral_radiance; +} + +float F(float theta, float gamma, in float[9] coeffs) { + float A = coeffs[0]; + float B = coeffs[1]; + float C = coeffs[2]; + float D = coeffs[3]; + float E = coeffs[4]; + float F = coeffs[5]; + float G = coeffs[6]; + float H = coeffs[8]; + float I = coeffs[7]; + float chi = (1.0 + pow(cos(gamma), 2.0)) / pow(1.0 + H*H - 2.0 * H * cos(gamma), 1.5); + + return ( + (1.0 + A * exp(B / (cos(theta) + 0.01))) * + (C + D * exp(E * gamma) + F * pow(cos(gamma), 2.0) + G * chi + I * sqrt(cos(theta))) + ); +} + +vec3 spectral_radiance(float theta, float gamma, int albedo, int turbidity, float sun_zenith) { + vec3 XYZ; + for (int i = 0; i < 3; ++i) { + float coeffs[9]; + get_coeffs(i, albedo, turbidity, sun_zenith, coeffs); + XYZ[i] = F(theta, gamma, coeffs); + } + return XYZ; +} + +// Returns angle between two directions defined by zentih and azimuth angles +float angle(float z1, float a1, float z2, float a2) { + return acos( + sin(z1) * cos(a1) * sin(z2) * cos(a2) + + sin(z1) * sin(a1) * sin(z2) * sin(a2) + + cos(z1) * cos(z2)); +} + +vec3 sample_sky(float view_zenith, float view_azimuth, float sun_zenith, float sun_azimuth) { + float gamma = angle(view_zenith, view_azimuth, sun_zenith, sun_azimuth); + float theta = view_zenith; + return spectral_radiance(theta, gamma, int(albedo), int(turbidity), sun_zenith) * mean_spectral_radiance(int(albedo), int(turbidity), sun_zenith); +} + +// CIE-XYZ to linear RGB +vec3 XYZ_to_RGB(vec3 XYZ) { + mat3 XYZ_to_linear = mat3( + 3.24096994, -0.96924364, 0.55630080, + -1.53738318, 1.8759675, -0.20397696, + -0.49861076, 0.04155506, 1.05697151 + ); + return XYZ_to_linear * XYZ; +} + +// Ad-hoc tonemapping, better approach should be used +vec3 tonemap(vec3 color, float exposure) { + return vec3(2.0) / (vec3(1.0) + exp(-exposure * color)) - vec3(1.0); +} + +void main() { + init(); + + vec2 uv = v_vTexcoord; + vec2 sun = sunPosition / dimension; + + uv.y = 1. - uv.y; + sun.y = 1. - sun.y; + + float sun_zenith = PI - sun.y * PI; + float sun_azimuth = PI + 2. * PI * sun.x; + + float view_zenith = PI - uv.y * PI; + float view_azimuth = PI + 2. * PI * uv.x; + + vec3 XYZ = sample_sky(view_zenith, view_azimuth, sun_zenith, sun_azimuth); + vec3 RGB = XYZ_to_RGB(XYZ); + vec3 col = tonemap(RGB, 0.1); + + gl_FragColor = vec4(col, 1.0); +} diff --git a/shaders/sh_sky_hosek/sh_sky_hosek.vsh b/shaders/sh_sky_hosek/sh_sky_hosek.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_sky_hosek/sh_sky_hosek.vsh @@ -0,0 +1,19 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +//attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() +{ + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_sky_hosek/sh_sky_hosek.yy b/shaders/sh_sky_hosek/sh_sky_hosek.yy new file mode 100644 index 000000000..fb582a555 --- /dev/null +++ b/shaders/sh_sky_hosek/sh_sky_hosek.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_sky_hosek", + "name":"sh_sky_hosek", + "parent":{ + "name":"sky model", + "path":"folders/shader/generator/sky model.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_sky_preetham/sh_sky_preetham.fsh b/shaders/sh_sky_preetham/sh_sky_preetham.fsh index 8a02377fb..c4e8d24e3 100644 --- a/shaders/sh_sky_preetham/sh_sky_preetham.fsh +++ b/shaders/sh_sky_preetham/sh_sky_preetham.fsh @@ -1,15 +1,17 @@ +// Preetham Sky +// By Althar +// https://www.shadertoy.com/view/llSSDR + #define PI 3.14159265359 varying vec2 v_vTexcoord; varying vec4 v_vColour; uniform vec2 dimension; -uniform vec2 position; -uniform vec2 scale; +uniform int mapping; uniform float turbidity; -uniform float azimuth; -uniform float inclination; +uniform vec2 sunPosition; float saturatedDot( in vec3 a, in vec3 b ) { return max( dot( a, b ), 0.0 ); @@ -44,7 +46,6 @@ vec3 XYZToRGB( in vec3 XYZ ) { return XYZ * M; } - vec3 YxyToRGB( in vec3 Yxy ) { vec3 XYZ = YxyToXYZ( Yxy ); vec3 RGB = XYZToRGB( XYZ ); @@ -105,9 +106,30 @@ vec3 calculateSkyLuminanceRGB( in vec3 s, in vec3 e, in float t ) { void main() { vec2 uv = v_vTexcoord; - uv = (uv - position / dimension); - uv.y = 1. - uv.y; - uv /= scale; + vec2 sun = sunPosition / dimension; + + // if(mapping == 0) { + uv.y = 1. - uv.y; + sun.y = 1. - sun.y; + + // } else if(mapping == 1) { + // float sun_angle = atan(sun.x, sun.y); + // float sun_distance = clamp(length(sun) * PI, 0.0, PI / 2.0 - 0.1); + + // float uv_angle = atan(uv.x,uv.y); + // float uv_distance = length(uv) * PI; + + // if (uv_distance > PI / 2.0) { + // gl_FragColor = vec4(vec3(0.0), 1.0); + // return; + // } + + // uv = vec2(uv_angle, uv_distance); + // sun = vec2(sun_angle, sun_distance); + // } + + float azimuth = PI + 2. * PI * sun.x; + float inclination = PI - sun.y * PI; vec3 sunDir = normalize( vec3( sin( inclination ) * cos( azimuth ), cos( inclination ), sin( inclination ) * sin(azimuth) ) ); vec3 viewDir = -computeSphericalCoordinates( uv ).xzy; diff --git a/shaders/sh_sky_scattering/sh_sky_scattering.fsh b/shaders/sh_sky_scattering/sh_sky_scattering.fsh new file mode 100644 index 000000000..53b35c5cc --- /dev/null +++ b/shaders/sh_sky_scattering/sh_sky_scattering.fsh @@ -0,0 +1,246 @@ +// Atmospheric Scattering +// Author: cubi +// https://www.shadertoy.com/view/XlBfRD +// License (MIT) Copyright (C) 2017-2018 Rui. All rights reserved. + +#define PI 3.1415926535 +#define PI_2 (3.1415926535 * 2.0) + +#define EPSILON 1e-5 +#define SAMPLES_NUMS 16 + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform int mapping; + +uniform vec2 sunPosition; +uniform float sunRadius; +uniform float sunRadiance; + +/*uniform*/ float mieG; +/*uniform*/ float mieHeight; +/*uniform*/ float rayleighHeight; + +vec3 waveLambdaMie; +vec3 waveLambdaOzone; +vec3 waveLambdaRayleigh; + +float earthRadius; +float earthAtmTopRadius; +vec3 earthCenter; + +float saturate(float x) { return clamp(x, 0.0, 1.0); } + +vec3 ComputeSphereNormal(vec2 coord, float phiStart, float phiLength, float thetaStart, float thetaLength) { + vec3 normal; + normal.x = -sin(thetaStart + coord.y * thetaLength) * sin(phiStart + coord.x * phiLength); + normal.y = -cos(thetaStart + coord.y * thetaLength); + normal.z = -sin(thetaStart + coord.y * thetaLength) * cos(phiStart + coord.x * phiLength); + return normalize(normal); +} + +vec2 ComputeRaySphereIntersection(vec3 position, vec3 dir, vec3 center, float radius) { + vec3 origin = position - center; + float B = dot(origin, dir); + float C = dot(origin, origin) - radius * radius; + float D = B * B - C; + + vec2 minimaxIntersections; + if (D < 0.0) { + minimaxIntersections = vec2(-1.0, -1.0); + + } else { + D = sqrt(D); + minimaxIntersections = vec2(-B - D, -B + D); + } + + return minimaxIntersections; +} + +vec3 ComputeWaveLambdaRayleigh(vec3 lambda) { + float n = 1.0003; + float N = 2.545E25; + float pn = 0.035; + float n2 = n * n; + float pi3 = PI * PI * PI; + float rayleighConst = (8.0 * pi3 * pow(n2 - 1.0, 2.0)) / (3.0 * N) * ((6.0 + 3.0 * pn) / (6.0 - 7.0 * pn)); + + return rayleighConst / (lambda * lambda * lambda * lambda); +} + +float ComputePhaseMie(float theta, float g) { + float g2 = g * g; + return (1.0 - g2) / pow(1.0 + g2 - 2.0 * g * saturate(theta), 1.5) / (4.0 * PI); +} + +float ComputePhaseRayleigh(float theta) { + float theta2 = theta * theta; + return (theta2 * 0.75 + 0.75) / (4.0 * PI); +} + +float ChapmanApproximation(float X, float h, float cosZenith) { + float c = sqrt(X + h); + float c_exp_h = c * exp(-h); + + if (cosZenith >= 0.0) { + return c_exp_h / (c * cosZenith + 1.0); + + } else { + float x0 = sqrt(1.0 - cosZenith * cosZenith) * (X + h); + float c0 = sqrt(x0); + + return 2.0 * c0 * exp(X - x0) - c_exp_h / (1.0 - c * cosZenith); + } +} + +float GetOpticalDepthSchueler(float h, float H, float earthRadius, float cosZenith) { + return H * ChapmanApproximation(earthRadius / H, h / H, cosZenith); +} + +vec3 GetTransmittance(vec3 L, vec3 V) { + float ch = GetOpticalDepthSchueler(L.y, rayleighHeight, earthRadius, V.y); + return exp(-(waveLambdaMie + waveLambdaRayleigh) * ch); +} + +vec2 ComputeOpticalDepth(vec3 samplePoint, vec3 V, vec3 L, float neg) { + float rl = length(samplePoint); + float h = rl - earthRadius; + vec3 r = samplePoint / rl; + + float cos_chi_sun = dot(r, L); + float cos_chi_ray = dot(r, V * neg); + + float opticalDepthSun = GetOpticalDepthSchueler(h, rayleighHeight, earthRadius, cos_chi_sun); + float opticalDepthCamera = GetOpticalDepthSchueler(h, rayleighHeight, earthRadius, cos_chi_ray) * neg; + + return vec2(opticalDepthSun, opticalDepthCamera); +} + +void AerialPerspective(vec3 start, vec3 end, vec3 V, vec3 L, bool infinite, out vec3 transmittance, out vec3 insctrMie, out vec3 insctrRayleigh) { + float inf_neg = infinite ? 1.0 : -1.0; + + vec3 sampleStep = (end - start) / float(SAMPLES_NUMS); + vec3 samplePoint = end - sampleStep; + vec3 sampleLambda = waveLambdaMie + waveLambdaRayleigh + waveLambdaOzone; + + float sampleLength = length(sampleStep); + + vec3 scattering = vec3(0.0); + vec2 lastOpticalDepth = ComputeOpticalDepth(end, V, L, inf_neg); + + for (int i = 1; i < SAMPLES_NUMS; i++, samplePoint -= sampleStep) { + vec2 opticalDepth = ComputeOpticalDepth(samplePoint, V, L, inf_neg); + + vec3 segment_s = exp(-sampleLambda * (opticalDepth.x + lastOpticalDepth.x)); + vec3 segment_t = exp(-sampleLambda * (opticalDepth.y - lastOpticalDepth.y)); + + transmittance *= segment_t; + + scattering = scattering * segment_t; + scattering += exp(-(length(samplePoint) - earthRadius) / rayleighHeight) * segment_s; + + lastOpticalDepth = opticalDepth; + } + + insctrMie = scattering * waveLambdaMie * sampleLength; + insctrRayleigh = scattering * waveLambdaRayleigh * sampleLength; +} + +float ComputeSkyboxChapman(vec3 eye, vec3 V, vec3 L, out vec3 transmittance, out vec3 insctrMie, out vec3 insctrRayleigh) { + bool neg = true; + + vec2 outerIntersections = ComputeRaySphereIntersection(eye, V, earthCenter, earthAtmTopRadius); + if (outerIntersections.y < 0.0) return 0.0; + + vec2 innerIntersections = ComputeRaySphereIntersection(eye, V, earthCenter, earthRadius); + if (innerIntersections.x > 0.0) { + neg = false; + outerIntersections.y = innerIntersections.x; + } + + eye -= earthCenter; + + vec3 start = eye + V * max(0.0, outerIntersections.x); + vec3 end = eye + V * outerIntersections.y; + + AerialPerspective(start, end, V, L, neg, transmittance, insctrMie, insctrRayleigh); + + bool intersectionTest = innerIntersections.x < 0.0 && innerIntersections.y < 0.0; + return intersectionTest ? 1.0 : 0.0; +} + +vec4 ComputeSkyInscattering(vec3 eye, vec3 V, vec3 L) { + vec3 insctrMie = vec3(0.0); + vec3 insctrRayleigh = vec3(0.0); + vec3 insctrOpticalLength = vec3(1.0); + float intersectionTest = ComputeSkyboxChapman(eye, V, L, insctrOpticalLength, insctrMie, insctrRayleigh); + + float phaseTheta = dot(V, L); + float phaseMie = ComputePhaseMie(phaseTheta, mieG); + float phaseRayleigh = ComputePhaseRayleigh(phaseTheta); + float phaseNight = 1.0 - saturate(insctrOpticalLength.x * EPSILON); + + vec3 insctrTotalMie = insctrMie * phaseMie; + vec3 insctrTotalRayleigh = insctrRayleigh * phaseRayleigh; + + vec3 sky = (insctrTotalMie + insctrTotalRayleigh) * sunRadiance; + + float angle = saturate((1.0 - phaseTheta) * sunRadius); + float cosAngle = cos(angle * PI * 0.5); + float edge = ((angle >= 0.9) ? smoothstep(0.9, 1.0, angle) : 0.0); + + vec3 limbDarkening = GetTransmittance(-L, V); + limbDarkening *= pow(vec3(cosAngle), vec3(0.420, 0.503, 0.652)) * mix(vec3(1.0), vec3(1.2,0.9,0.5), edge) * intersectionTest; + + sky += limbDarkening; + + return vec4(sky, phaseNight * intersectionTest); +} + +vec3 TonemapACES(vec3 x) { + float A = 2.51; + float B = 0.03; + float C = 2.43; + float D = 0.59; + float E = 0.14; + return (x * (A * x + B)) / (x * (C * x + D) + E); +} + +float noise(vec2 uv) { + return fract(dot(sin(uv.xyx * uv.xyy * 1024.0), vec3(341896.483, 891618.637, 602649.7031))); +} + +void main() { + vec2 uv = v_vTexcoord; + vec2 sun = sunPosition / dimension; + + uv.y = 1. - uv.y; + sun.y = 1. - sun.y; + + vec3 V = ComputeSphereNormal(uv, 0.0, PI_2, 0.0, PI); + vec3 L = ComputeSphereNormal(vec2(sun.x, sun.y), 0.0, PI_2, 0.0, PI); + + mieG = 0.76; + mieHeight = 1200.0; + rayleighHeight = 8000.0; + + earthRadius = 6360000.0; + earthAtmTopRadius = 6420000.0; + earthCenter = vec3(0, -earthRadius, 0); + waveLambdaMie = vec3(2e-7); + + // wavelength with 680nm, 550nm, 450nm + waveLambdaRayleigh = ComputeWaveLambdaRayleigh(vec3(680e-9, 550e-9, 450e-9)); + + // see https://www.shadertoy.com/view/MllBR2 + waveLambdaOzone = vec3(1.36820899679147, 3.31405330400124, 0.13601728252538) * 0.6e-6 * 2.504; + + vec3 eye = vec3(0., 1000.0, 0.); + vec4 sky = ComputeSkyInscattering(eye, V, L); + sky.rgb = TonemapACES(sky.rgb * 2.0); + sky.rgb = pow(sky.rgb, vec3(1.0 / 2.2)); // gamma + + gl_FragColor = vec4(sky.rgb, 1.0); +} diff --git a/shaders/sh_sky_scattering/sh_sky_scattering.vsh b/shaders/sh_sky_scattering/sh_sky_scattering.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_sky_scattering/sh_sky_scattering.vsh @@ -0,0 +1,19 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +//attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() +{ + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_sky_scattering/sh_sky_scattering.yy b/shaders/sh_sky_scattering/sh_sky_scattering.yy new file mode 100644 index 000000000..38b1b58db --- /dev/null +++ b/shaders/sh_sky_scattering/sh_sky_scattering.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_sky_scattering", + "name":"sh_sky_scattering", + "parent":{ + "name":"sky model", + "path":"folders/shader/generator/sky model.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/sprites/s_node_sky/68373dee-c8d3-42f8-a753-ddf0f15676ed.png b/sprites/s_node_sky/68373dee-c8d3-42f8-a753-ddf0f15676ed.png new file mode 100644 index 0000000000000000000000000000000000000000..487556819e30d7e50e88794483edc354b29cdbe7 GIT binary patch literal 2803 zcmZ{mc{mh$7sr1ygD}>}l6{wTWShtsB4nE|DUp%g*hyrFu}vs$)+}8@O+;i#CB_zR zwjyL5=|*-j$XH(YpZ9&`u`*$2J0vN=}tKgrB= zT+6+KrjJG3)zrokfIG4P#KZ%zcif6u0N@q^fJGbtI=KMw2Nt}&eE!&Ax@m4=1djfR zqW8}-0ATrHW@KO&KE9H#n+K@z{Qz9wWMx~Cd=t`O<)svF1{eEeF zI2zt0B`J0T6nP(x{)wA?E#9Q5-s-2)L_f)Fov|_XyE7Zo!qALrIXw9DsAuQyF8pw7 zhZBP(XE`V$(mo1}zUlT*h!K9!FY)TRqiGZqb;ehCTDzIZO;lg%|^DzoVL{d$6wGZ!3l{aeERx+MLOqXD>o4yWb{!H@9>mMRnNp-IE^xMj* z;qZ)_=_>dfD5iqtg+o4z2H@DI%mL6^|K({gR;Zlnuf12v{p2E<|*mM@5#fcyH>AH&TXu$MgVg$}%s4RgB0JxUKtP^N1Ld z+jdHs@e?${VSnI@V0G&CwSice210AiYdC=SNwRp?W!HA0rP`ewEvAq}iCI^Z1uN5b z#jTySPc!CQazyJQ!R<6C>S7?rm*i~29-fDC9rsfP!Y$h9yll9o@85~<)K!&)bJ2e0 zLUG7c&du@{6_OsZNcA`ws5AkgPHIQr&O=6Fk$Q25yiY|4TNpA!uxR(3k?2liwaMgk zuh~A$vPjf-SnJvu_Eg#I;ZqD>2P0q)l^$Ha66Tw5!_Z^G3!YS~x?UsIVYC>(%4;P? zd9OZpa3VNy!%@K2EmcHCx}$6R@c#PfFNktHR!!)!K{eMx-g<3Q@H$E>f+8twSQtWd zE$&nuf2}4yEu|uf`bKOwUgvHK(A}U)HpVz{2A!HtVseAU;vrOJJ7pmJYi^J(rdA*| z+j)&GQ>wDtqtCB?&EA;`{pQ{y7@W8%Vj*Ro&aJBKlGpB5(vnZt1YGku7|n@ycEwkc z>^`!o?kGe3M;fl%;##IM{VcSIQZ9u78uxNJKi?$U_pXK{QB7h z=fVZ(^yJH4AXbxk5pyQ{OZ~2@^1k2&4ju__pu{+6v-RS4vmZjVx6s*uJ3xd#|IyeG zwvWL>i&qn8;o=V&Mmzl}rQ$3G3fiAPsj9QiuQkxhqMlxMn}fOKQ%x&Y9hy~9k`k4V zCrmozCZQL79eB;lgy41V^_3T|D_Irf{*E8JV;J1_I~6`^n&4zg#(TfubHwKQwXhr^ zwdM2m;V?HEBqd~%n?EC#OIJE{X-OGjFhc5CjJ`#W^>At&JSnfQU()V(! zuW2J^r?{^N2?l1;dfhi1XLPR#R@)J3+B>Iz?T@`GeH8(7sR)?beSvZZbY5e{&M7V?Ka|k7@C)e1Iy%M#*!N`C_G_Y z0PJ053>f7|GZK9*3x`cE!wjX36z|+TO`1Y4T9Gb15kf9_GnFtVmQ#N{bW`bXO#}sb zLo}w{EXcy@dqXGa3J>|Nrh+iwGW2>AZDOidvt;HZ&TgoU)<@rd1xxrhMsyG3OMp{X7n+65h_8ZKnjRdvC9e}wvuBV5-Kz5fsSM@?x0u0vsXXB(8c$999 z(3@HG(RZO2IHThG4Nk6KwJ!=6fGzVZM~=~|Cp5XjM!NJ;>3Crh;c(eC{NNeXfMuG8 zn7f@Zc>C#3mza#!53TLugOKNb;i#+q6zRa#O8sBeaJ+t6^-Ozolg3474$AyDlL3Cv z8^pL_B}K7J)A0&1hJAit*m|#cNRqsCJzURa zHFyQxYISA?4d}6)vq)s(UB1peIE11mF!1V4+7XHW-4rBnNT~5=*a?bd0QKpF2+)2X zo9}-cOl~pxzx|)-aTpjmyS$Z9k)h(ZLx<0tyxy!?&qzI35ebN%74>{J%i^rwd|-(% zZl;ydyKjm4SjvL{p$4*L_l`j^TpS?;~x>ogc@HBb#n=I*KrMYKNfHnaaKcF4WWD% zVTU-UqoJ*X&{RYqbPx!Sex9!X1N;KqygefR9pKNXh&%@5|GOd7+s{2D)Wt9G-x+jb Ra_KPx%#5v!stj?&{{RJC2OIzZ literal 0 HcmV?d00001 diff --git a/sprites/s_node_sky/layers/68373dee-c8d3-42f8-a753-ddf0f15676ed/f370aa54-fd4b-4081-bb69-366f6a87e8e6.png b/sprites/s_node_sky/layers/68373dee-c8d3-42f8-a753-ddf0f15676ed/f370aa54-fd4b-4081-bb69-366f6a87e8e6.png new file mode 100644 index 0000000000000000000000000000000000000000..487556819e30d7e50e88794483edc354b29cdbe7 GIT binary patch literal 2803 zcmZ{mc{mh$7sr1ygD}>}l6{wTWShtsB4nE|DUp%g*hyrFu}vs$)+}8@O+;i#CB_zR zwjyL5=|*-j$XH(YpZ9&`u`*$2J0vN=}tKgrB= zT+6+KrjJG3)zrokfIG4P#KZ%zcif6u0N@q^fJGbtI=KMw2Nt}&eE!&Ax@m4=1djfR zqW8}-0ATrHW@KO&KE9H#n+K@z{Qz9wWMx~Cd=t`O<)svF1{eEeF zI2zt0B`J0T6nP(x{)wA?E#9Q5-s-2)L_f)Fov|_XyE7Zo!qALrIXw9DsAuQyF8pw7 zhZBP(XE`V$(mo1}zUlT*h!K9!FY)TRqiGZqb;ehCTDzIZO;lg%|^DzoVL{d$6wGZ!3l{aeERx+MLOqXD>o4yWb{!H@9>mMRnNp-IE^xMj* z;qZ)_=_>dfD5iqtg+o4z2H@DI%mL6^|K({gR;Zlnuf12v{p2E<|*mM@5#fcyH>AH&TXu$MgVg$}%s4RgB0JxUKtP^N1Ld z+jdHs@e?${VSnI@V0G&CwSice210AiYdC=SNwRp?W!HA0rP`ewEvAq}iCI^Z1uN5b z#jTySPc!CQazyJQ!R<6C>S7?rm*i~29-fDC9rsfP!Y$h9yll9o@85~<)K!&)bJ2e0 zLUG7c&du@{6_OsZNcA`ws5AkgPHIQr&O=6Fk$Q25yiY|4TNpA!uxR(3k?2liwaMgk zuh~A$vPjf-SnJvu_Eg#I;ZqD>2P0q)l^$Ha66Tw5!_Z^G3!YS~x?UsIVYC>(%4;P? zd9OZpa3VNy!%@K2EmcHCx}$6R@c#PfFNktHR!!)!K{eMx-g<3Q@H$E>f+8twSQtWd zE$&nuf2}4yEu|uf`bKOwUgvHK(A}U)HpVz{2A!HtVseAU;vrOJJ7pmJYi^J(rdA*| z+j)&GQ>wDtqtCB?&EA;`{pQ{y7@W8%Vj*Ro&aJBKlGpB5(vnZt1YGku7|n@ycEwkc z>^`!o?kGe3M;fl%;##IM{VcSIQZ9u78uxNJKi?$U_pXK{QB7h z=fVZ(^yJH4AXbxk5pyQ{OZ~2@^1k2&4ju__pu{+6v-RS4vmZjVx6s*uJ3xd#|IyeG zwvWL>i&qn8;o=V&Mmzl}rQ$3G3fiAPsj9QiuQkxhqMlxMn}fOKQ%x&Y9hy~9k`k4V zCrmozCZQL79eB;lgy41V^_3T|D_Irf{*E8JV;J1_I~6`^n&4zg#(TfubHwKQwXhr^ zwdM2m;V?HEBqd~%n?EC#OIJE{X-OGjFhc5CjJ`#W^>At&JSnfQU()V(! zuW2J^r?{^N2?l1;dfhi1XLPR#R@)J3+B>Iz?T@`GeH8(7sR)?beSvZZbY5e{&M7V?Ka|k7@C)e1Iy%M#*!N`C_G_Y z0PJ053>f7|GZK9*3x`cE!wjX36z|+TO`1Y4T9Gb15kf9_GnFtVmQ#N{bW`bXO#}sb zLo}w{EXcy@dqXGa3J>|Nrh+iwGW2>AZDOidvt;HZ&TgoU)<@rd1xxrhMsyG3OMp{X7n+65h_8ZKnjRdvC9e}wvuBV5-Kz5fsSM@?x0u0vsXXB(8c$999 z(3@HG(RZO2IHThG4Nk6KwJ!=6fGzVZM~=~|Cp5XjM!NJ;>3Crh;c(eC{NNeXfMuG8 zn7f@Zc>C#3mza#!53TLugOKNb;i#+q6zRa#O8sBeaJ+t6^-Ozolg3474$AyDlL3Cv z8^pL_B}K7J)A0&1hJAit*m|#cNRqsCJzURa zHFyQxYISA?4d}6)vq)s(UB1peIE11mF!1V4+7XHW-4rBnNT~5=*a?bd0QKpF2+)2X zo9}-cOl~pxzx|)-aTpjmyS$Z9k)h(ZLx<0tyxy!?&qzI35ebN%74>{J%i^rwd|-(% zZl;ydyKjm4SjvL{p$4*L_l`j^TpS?;~x>ogc@HBb#n=I*KrMYKNfHnaaKcF4WWD% zVTU-UqoJ*X&{RYqbPx!Sex9!X1N;KqygefR9pKNXh&%@5|GOd7+s{2D)Wt9G-x+jb Ra_KPx%#5v!stj?&{{RJC2OIzZ literal 0 HcmV?d00001 diff --git a/sprites/s_node_sky/s_node_sky.yy b/sprites/s_node_sky/s_node_sky.yy new file mode 100644 index 000000000..49e2eadcb --- /dev/null +++ b/sprites/s_node_sky/s_node_sky.yy @@ -0,0 +1,90 @@ +{ + "$GMSprite":"", + "%Name":"s_node_sky", + "bboxMode":0, + "bbox_bottom":61, + "bbox_left":2, + "bbox_right":61, + "bbox_top":2, + "collisionKind":1, + "collisionTolerance":0, + "DynamicTexturePage":false, + "edgeFiltering":false, + "For3D":false, + "frames":[ + {"$GMSpriteFrame":"","%Name":"68373dee-c8d3-42f8-a753-ddf0f15676ed","name":"68373dee-c8d3-42f8-a753-ddf0f15676ed","resourceType":"GMSpriteFrame","resourceVersion":"2.0",}, + ], + "gridX":0, + "gridY":0, + "height":64, + "HTile":false, + "layers":[ + {"$GMImageLayer":"","%Name":"f370aa54-fd4b-4081-bb69-366f6a87e8e6","blendMode":0,"displayName":"default","isLocked":false,"name":"f370aa54-fd4b-4081-bb69-366f6a87e8e6","opacity":100.0,"resourceType":"GMImageLayer","resourceVersion":"2.0","visible":true,}, + ], + "name":"s_node_sky", + "nineSlice":null, + "origin":4, + "parent":{ + "name":"generator", + "path":"folders/nodes/icons/generator.yy", + }, + "preMultiplyAlpha":false, + "resourceType":"GMSprite", + "resourceVersion":"2.0", + "sequence":{ + "$GMSequence":"", + "%Name":"s_node_sky", + "autoRecord":true, + "backdropHeight":768, + "backdropImageOpacity":0.5, + "backdropImagePath":"", + "backdropWidth":1366, + "backdropXOffset":0.0, + "backdropYOffset":0.0, + "events":{ + "$KeyframeStore":"", + "Keyframes":[], + "resourceType":"KeyframeStore", + "resourceVersion":"2.0", + }, + "eventStubScript":null, + "eventToFunction":{}, + "length":1.0, + "lockOrigin":false, + "moments":{ + "$KeyframeStore":"", + "Keyframes":[], + "resourceType":"KeyframeStore", + "resourceVersion":"2.0", + }, + "name":"s_node_sky", + "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":"","Keyframes":[ + {"$Keyframe":"","Channels":{ + "0":{"$SpriteFrameKeyframe":"","Id":{"name":"68373dee-c8d3-42f8-a753-ddf0f15676ed","path":"sprites/s_node_sky/s_node_sky.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",}, + },"Disabled":false,"id":"8145cea0-1720-4def-8afe-111dbdb8ee79","IsCreationKey":false,"Key":0.0,"Length":1.0,"resourceType":"Keyframe","resourceVersion":"2.0","Stretch":false,}, + ],"resourceType":"KeyframeStore","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, +} \ No newline at end of file