mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-11-14 14:33:53 +01:00
New Sky generator node.
This commit is contained in:
parent
68035d8ec7
commit
1790d564ca
@ -1744,6 +1744,8 @@
|
|||||||
{"name":"sh_shape_map_polygon","order":15,"path":"shaders/sh_shape_map_polygon/sh_shape_map_polygon.yy",},
|
{"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_simplex","order":16,"path":"shaders/sh_simplex/sh_simplex.yy",},
|
||||||
{"name":"sh_skew","order":6,"path":"shaders/sh_skew/sh_skew.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_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_smear","order":13,"path":"shaders/sh_smear/sh_smear.yy",},
|
||||||
{"name":"sh_solid","order":5,"path":"shaders/sh_solid/sh_solid.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_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_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_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_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_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",},
|
{"name":"s_node_smokeSim_add_collider","order":6,"path":"sprites/s_node_smokeSim_add_collider/s_node_smokeSim_add_collider.yy",},
|
||||||
|
@ -2440,7 +2440,9 @@
|
|||||||
{"id":{"name":"sh_shape","path":"shaders/sh_shape/sh_shape.yy",},},
|
{"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_simplex","path":"shaders/sh_simplex/sh_simplex.yy",},},
|
||||||
{"id":{"name":"sh_skew","path":"shaders/sh_skew/sh_skew.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_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_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_smear","path":"shaders/sh_smear/sh_smear.yy",},},
|
||||||
{"id":{"name":"sh_solid","path":"shaders/sh_solid/sh_solid.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_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_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_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_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_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",},},
|
{"id":{"name":"s_node_smokeSim_add_collider","path":"sprites/s_node_smokeSim_add_collider/s_node_smokeSim_add_collider.yy",},},
|
||||||
|
@ -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, "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 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, "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");
|
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.");
|
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.");
|
||||||
|
@ -3,25 +3,32 @@ function Node_Sky(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) const
|
|||||||
|
|
||||||
newInput(0, nodeValue_Dimension(self));
|
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))
|
newInput(3, nodeValue_Enum_Scroll("Model", self, 0, [ "Preetham", "Basic scattering", "Hosek" ]));
|
||||||
.setDisplay(VALUE_DISPLAY.slider, { range: [ -180, 180, 1 ] });
|
|
||||||
|
|
||||||
newInput(4, nodeValue_Float("Inclination", self, 0))
|
newInput(4, nodeValue_Float("Turbidity", self, 2));
|
||||||
.setDisplay(VALUE_DISPLAY.slider, { range: [ -180, 180, 1 ] });
|
|
||||||
|
|
||||||
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));
|
newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone));
|
||||||
|
|
||||||
input_display_list = [ 0,
|
input_display_list = [ 0,
|
||||||
["Transform", false], 6, 5,
|
// ["Transform", false], 1, 2,
|
||||||
["Sky", false], 1, 2, 3, 4,
|
["Sky", false], 3, 4, 8,
|
||||||
|
["Sun", false], 5, 6, 7,
|
||||||
|
//["Render", false], 9,
|
||||||
];
|
];
|
||||||
|
|
||||||
attribute_surface_depth();
|
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) {
|
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
|
||||||
var _hov = false;
|
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;
|
return _hov;
|
||||||
}
|
}
|
||||||
|
|
||||||
static processData = function(_outSurf, _data, _output_index, _array_index) {
|
static processData = function(_outSurf, _data, _output_index, _array_index) {
|
||||||
var _dim = _data[0];
|
var _dim = _data[0];
|
||||||
var _mod = _data[1];
|
var _pos = _data[1];
|
||||||
var _tur = _data[2];
|
var _sca = _data[2];
|
||||||
var _azi = _data[3];
|
|
||||||
var _inc = _data[4];
|
var _mod = _data[3];
|
||||||
var _sca = _data[5];
|
var _tur = _data[4];
|
||||||
var _pos = _data[6];
|
var _sun = _data[5];
|
||||||
|
var _sunRad = _data[6];
|
||||||
|
var _sunRdd = _data[7];
|
||||||
|
var _alb = _data[8];
|
||||||
|
var _map = _data[9];
|
||||||
|
|
||||||
if(_mod == 0) {
|
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);
|
surface_set_shader(_outSurf, sh_sky_preetham);
|
||||||
DRAW_CLEAR
|
DRAW_CLEAR
|
||||||
|
|
||||||
shader_set_2("dimension", _dim);
|
shader_set_2("dimension", _dim);
|
||||||
shader_set_2("position", _pos);
|
shader_set_2("sunPosition", _sun);
|
||||||
shader_set_2("scale", _sca);
|
|
||||||
shader_set_f("turbidity", _tur);
|
shader_set_f("turbidity", _tur);
|
||||||
shader_set_f("azimuth", degtorad(_azi));
|
shader_set_i("mapping", _map);
|
||||||
shader_set_f("inclination", degtorad(_inc));
|
|
||||||
|
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();
|
draw_empty();
|
||||||
surface_reset_shader();
|
surface_reset_shader();
|
||||||
|
401
shaders/sh_sky_hosek/sh_sky_hosek.fsh
Normal file
401
shaders/sh_sky_hosek/sh_sky_hosek.fsh
Normal file
@ -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);
|
||||||
|
}
|
19
shaders/sh_sky_hosek/sh_sky_hosek.vsh
Normal file
19
shaders/sh_sky_hosek/sh_sky_hosek.vsh
Normal file
@ -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;
|
||||||
|
}
|
12
shaders/sh_sky_hosek/sh_sky_hosek.yy
Normal file
12
shaders/sh_sky_hosek/sh_sky_hosek.yy
Normal file
@ -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,
|
||||||
|
}
|
@ -1,15 +1,17 @@
|
|||||||
|
// Preetham Sky
|
||||||
|
// By Althar
|
||||||
|
// https://www.shadertoy.com/view/llSSDR
|
||||||
|
|
||||||
#define PI 3.14159265359
|
#define PI 3.14159265359
|
||||||
|
|
||||||
varying vec2 v_vTexcoord;
|
varying vec2 v_vTexcoord;
|
||||||
varying vec4 v_vColour;
|
varying vec4 v_vColour;
|
||||||
|
|
||||||
uniform vec2 dimension;
|
uniform vec2 dimension;
|
||||||
uniform vec2 position;
|
uniform int mapping;
|
||||||
uniform vec2 scale;
|
|
||||||
|
|
||||||
uniform float turbidity;
|
uniform float turbidity;
|
||||||
uniform float azimuth;
|
uniform vec2 sunPosition;
|
||||||
uniform float inclination;
|
|
||||||
|
|
||||||
float saturatedDot( in vec3 a, in vec3 b ) {
|
float saturatedDot( in vec3 a, in vec3 b ) {
|
||||||
return max( dot( a, b ), 0.0 );
|
return max( dot( a, b ), 0.0 );
|
||||||
@ -44,7 +46,6 @@ vec3 XYZToRGB( in vec3 XYZ ) {
|
|||||||
return XYZ * M;
|
return XYZ * M;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 YxyToRGB( in vec3 Yxy ) {
|
vec3 YxyToRGB( in vec3 Yxy ) {
|
||||||
vec3 XYZ = YxyToXYZ( Yxy );
|
vec3 XYZ = YxyToXYZ( Yxy );
|
||||||
vec3 RGB = XYZToRGB( XYZ );
|
vec3 RGB = XYZToRGB( XYZ );
|
||||||
@ -105,9 +106,30 @@ vec3 calculateSkyLuminanceRGB( in vec3 s, in vec3 e, in float t ) {
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = v_vTexcoord;
|
vec2 uv = v_vTexcoord;
|
||||||
uv = (uv - position / dimension);
|
vec2 sun = sunPosition / dimension;
|
||||||
uv.y = 1. - uv.y;
|
|
||||||
uv /= scale;
|
// 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 sunDir = normalize( vec3( sin( inclination ) * cos( azimuth ), cos( inclination ), sin( inclination ) * sin(azimuth) ) );
|
||||||
vec3 viewDir = -computeSphericalCoordinates( uv ).xzy;
|
vec3 viewDir = -computeSphericalCoordinates( uv ).xzy;
|
||||||
|
246
shaders/sh_sky_scattering/sh_sky_scattering.fsh
Normal file
246
shaders/sh_sky_scattering/sh_sky_scattering.fsh
Normal file
@ -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);
|
||||||
|
}
|
19
shaders/sh_sky_scattering/sh_sky_scattering.vsh
Normal file
19
shaders/sh_sky_scattering/sh_sky_scattering.vsh
Normal file
@ -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;
|
||||||
|
}
|
12
shaders/sh_sky_scattering/sh_sky_scattering.yy
Normal file
12
shaders/sh_sky_scattering/sh_sky_scattering.yy
Normal file
@ -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,
|
||||||
|
}
|
BIN
sprites/s_node_sky/68373dee-c8d3-42f8-a753-ddf0f15676ed.png
Normal file
BIN
sprites/s_node_sky/68373dee-c8d3-42f8-a753-ddf0f15676ed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
90
sprites/s_node_sky/s_node_sky.yy
Normal file
90
sprites/s_node_sky/s_node_sky.yy
Normal file
@ -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<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_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<SpriteFrameKeyframe>":"","Keyframes":[
|
||||||
|
{"$Keyframe<SpriteFrameKeyframe>":"","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<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,
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user