From 56455a603290b37ee74ab15daba8cd2ad64a95f3 Mon Sep 17 00:00:00 2001 From: ruofeidu Date: Sun, 17 Dec 2017 15:44:45 -0500 Subject: [PATCH] Stable version v1. --- Colors/Natural.cmd | 1 + Colors/Natural.glsl | 24 ++ Colors/Natural.ini | 3 + Colors/_create.cmd | 1 + Distortion/_create.cmd | 2 +- DuEngine/DuEngine.cpp | 8 +- DuEngine/DuScene.cpp | 3 +- DuEngine/DuUtils.cpp | 43 +++- DuEngine/DuUtils.h | 8 +- DuEngine/stdafx.h | 2 +- DuShaders/0-5OrdersSphericalHarmonics.cmd | 1 + DuShaders/0-5OrdersSphericalHarmonics.glsl | 262 +++++++++++++++++++++ DuShaders/0-5OrdersSphericalHarmonics.ini | 12 + ShaderOfWeek/NotebookDrawing.cmd | 1 + ShaderOfWeek/NotebookDrawing.glsl | 114 +++++++++ ShaderOfWeek/NotebookDrawing.ini | 6 + 16 files changed, 481 insertions(+), 10 deletions(-) create mode 100644 Colors/Natural.cmd create mode 100644 Colors/Natural.glsl create mode 100644 Colors/Natural.ini create mode 100644 Colors/_create.cmd create mode 100644 DuShaders/0-5OrdersSphericalHarmonics.cmd create mode 100644 DuShaders/0-5OrdersSphericalHarmonics.glsl create mode 100644 DuShaders/0-5OrdersSphericalHarmonics.ini create mode 100644 ShaderOfWeek/NotebookDrawing.cmd create mode 100644 ShaderOfWeek/NotebookDrawing.glsl create mode 100644 ShaderOfWeek/NotebookDrawing.ini diff --git a/Colors/Natural.cmd b/Colors/Natural.cmd new file mode 100644 index 0000000..2c094e9 --- /dev/null +++ b/Colors/Natural.cmd @@ -0,0 +1 @@ +"../DuEngine/x64/Release/DuEngine.exe" %~n0.ini diff --git a/Colors/Natural.glsl b/Colors/Natural.glsl new file mode 100644 index 0000000..f5ea461 --- /dev/null +++ b/Colors/Natural.glsl @@ -0,0 +1,24 @@ +// https://www.shadertoy.com/view/MlcGD7 +// see also full black body spectrum: https://www.shadertoy.com/view/4tdGWM +// deeper in fluids: https://www.shadertoy.com/view/XldGDM + +void mainImage( out vec4 O, vec2 U ) +{ + U /= iResolution.xy; + float y = 2.* U.y; + + O = + // secret 1 for natural colors for luminous phenomena: + // - real-life color spectrum is never zero in any channel + // - intensities are 0 to infinity + // - captors (camera,eye) saturates early + y > 1. ? vec4(1,1./4.,1./16.,1) * exp(4.*U.x - 1.) // i.e. exp(T) * exp(-z) + + // secret 2 for natural colors for volumetric phenomena: + // - transparency decrease as the power of distance ( T^l ) + // - T value varies with frequency ( i.e. color channel ) + // - real life transparency is never exactly 1 at any frequency + : pow(vec4(.1, .7, .8, 1), vec4(4.*U.x)); + + +} \ No newline at end of file diff --git a/Colors/Natural.ini b/Colors/Natural.ini new file mode 100644 index 0000000..4b076e6 --- /dev/null +++ b/Colors/Natural.ini @@ -0,0 +1,3 @@ +shader_frag = $Name.glsl +channels_count = 1 +iChannel0_type = London diff --git a/Colors/_create.cmd b/Colors/_create.cmd new file mode 100644 index 0000000..f740177 --- /dev/null +++ b/Colors/_create.cmd @@ -0,0 +1 @@ +python "../Scripts/_create.py" \ No newline at end of file diff --git a/Distortion/_create.cmd b/Distortion/_create.cmd index ec51495..f740177 100644 --- a/Distortion/_create.cmd +++ b/Distortion/_create.cmd @@ -1 +1 @@ -"python" "../Scripts/_create.py" \ No newline at end of file +python "../Scripts/_create.py" \ No newline at end of file diff --git a/DuEngine/DuEngine.cpp b/DuEngine/DuEngine.cpp index 3bf473e..20cf6b7 100644 --- a/DuEngine/DuEngine.cpp +++ b/DuEngine/DuEngine.cpp @@ -91,13 +91,13 @@ void DuEngine::start(int argc, char* argv[]) { m_path = new PathManager(std::string(argv[0]), m_config); // setup the default m_window width and height - m_defaultWidth = m_config->GetIntWithDefault("window_width", m_defaultWidth); - m_defaultHeight = m_config->GetIntWithDefault("window_height", m_defaultHeight); - string _windowTitle = m_config->GetStringWithDefault("window_title", "DuRenderer | " + m_config->GetName()); + m_defaultWidth = m_config->GetIntWithDefault("window_width", m_config->GetIntWithDefault("width", m_defaultWidth)); + m_defaultHeight = m_config->GetIntWithDefault("window_height", m_config->GetIntWithDefault("height", m_defaultHeight)); + string _windowTitle = m_config->GetStringWithDefault("window_title", m_config->GetStringWithDefault("title", "DuRenderer | " + m_config->GetName())); m_window->init(argc, argv, m_defaultWidth, m_defaultHeight, _windowTitle); // setup recording - m_recording = m_config->GetBoolWithDefault("recording", m_recording); + m_recording = m_config->GetBoolWithDefault("record", m_config->GetBoolWithDefault("recording", m_recording)); m_recordPath = m_config->GetStringWithDefault("record_path", m_config->GetName()); m_recordStart = m_config->GetIntWithDefault("record_start", m_recordStart); m_recordEnd = m_config->GetIntWithDefault("record_end", m_recordEnd); diff --git a/DuEngine/DuScene.cpp b/DuEngine/DuScene.cpp index b7eeab0..64b88f9 100644 --- a/DuEngine/DuScene.cpp +++ b/DuEngine/DuScene.cpp @@ -32,8 +32,7 @@ void DuEngine::initScene() { auto channels_count = m_config->GetIntWithDefault(prefix + "channels_count", 0); for (int i = 0; i < channels_count; ++i) { string iPrefix = prefix + "iChannel" + to_string(i) + "_"; - auto type = m_config->GetStringWithDefault(iPrefix + "type", "unknown"); - std::transform(type.begin(), type.end(), type.begin(), ::tolower); + auto type = toLower(m_config->GetStringWithDefault(iPrefix + "type", "unknown")); auto fileName = m_path->getResource(iPrefix + "tex"); Texture::QueryFileNameByType(type, fileName, m_path->getPresetPath()); auto textureType = Texture::QueryType(type); diff --git a/DuEngine/DuUtils.cpp b/DuEngine/DuUtils.cpp index d04ecb2..e878cf2 100644 --- a/DuEngine/DuUtils.cpp +++ b/DuEngine/DuUtils.cpp @@ -8,7 +8,7 @@ #include "stdafx.h" #include "DuUtils.h" -bool dirExists(const std::string& dirName_in) { +bool dirExists(const string& dirName_in) { DWORD ftyp = GetFileAttributesA(dirName_in.c_str()); if (ftyp == INVALID_FILE_ATTRIBUTES) return false; //something is wrong with your path! @@ -61,6 +61,47 @@ string repeatstring(string s, int cnt) { return res; } +string toLower(const string & value) { + string result; + result.resize(value.size()); + std::transform(value.begin(), value.end(), result.begin(), ::tolower); + return result; +} + +bool toBool(const string & str) { + string value = toLower(str); + if (value == "false") + return false; + else if (value == "true") + return true; + warning("Could not parse boolean value " + str); + return false; +} + +int toInt(const string & str) { + char *end_ptr = nullptr; + int result = (int)strtol(str.c_str(), &end_ptr, 10); + if (*end_ptr != '\0') + warning("Could not parse integer value \"%s\"" + str); + return result; +} + +unsigned int toUInt(const string & str) { + char *end_ptr = nullptr; + unsigned int result = (int)strtoul(str.c_str(), &end_ptr, 10); + if (*end_ptr != '\0') + warning("Could not parse integer value \"%s\"" + str); + return result; +} + +float toFloat(const string & str) { + char *end_ptr = nullptr; + float result = (float)strtof(str.c_str(), &end_ptr); + if (*end_ptr != '\0') + warning("Could not parse floating point value \"%s\"" + str);; + return result; +} + void onError() { system("pause"); exit(EXIT_FAILURE); diff --git a/DuEngine/DuUtils.h b/DuEngine/DuUtils.h index 951460a..06c608c 100644 --- a/DuEngine/DuUtils.h +++ b/DuEngine/DuUtils.h @@ -10,12 +10,18 @@ void dump(char* pszFormat, ...); void onError(); // file systems -bool dirExists(const std::string& dirName_in); +bool dirExists(const string& dirName_in); string getTimeForFileName(); // string utilities string repeatstring(string s, int cnt); +string toLower(const string &value); +bool toBool(const string &str); +int toInt(const string &str); +unsigned int toUInt(const string &str); +float toFloat(const string &str); + // design pattern utilities class Singleton { diff --git a/DuEngine/stdafx.h b/DuEngine/stdafx.h index 03a2e03..82a3597 100644 --- a/DuEngine/stdafx.h +++ b/DuEngine/stdafx.h @@ -57,7 +57,7 @@ const float PI = 3.14159265359f; #define DEBUG_VIDEO 0 #define DEBUG_PATH 0 #define DEBUG_TEXTURE_DEPRECATED_FILTERING 0 -#define VERBOSE_OUTPUT 1 +#define VERBOSE_OUTPUT 0 #if COMPILE_WITH_SH #include "SHUtils.h" diff --git a/DuShaders/0-5OrdersSphericalHarmonics.cmd b/DuShaders/0-5OrdersSphericalHarmonics.cmd new file mode 100644 index 0000000..2c094e9 --- /dev/null +++ b/DuShaders/0-5OrdersSphericalHarmonics.cmd @@ -0,0 +1 @@ +"../DuEngine/x64/Release/DuEngine.exe" %~n0.ini diff --git a/DuShaders/0-5OrdersSphericalHarmonics.glsl b/DuShaders/0-5OrdersSphericalHarmonics.glsl new file mode 100644 index 0000000..249907a --- /dev/null +++ b/DuShaders/0-5OrdersSphericalHarmonics.glsl @@ -0,0 +1,262 @@ +// Created by inigo quilez - iq/2013 +// Added the 4th order of SH - ruofei/2017 +// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. + +// Five bands of Spherical Harmonics functions (or atomic orbitals if you want). +// For reference and fun. + + + +// antialias level (try 1, 2, 3, ...) +#define AA 1 +// change TIME to 0 to stop rotating +#define TIME iTime + +//#define SHOW_SPHERES + +//--------------------------------------------------------------------------------- + +// Constants, see here: http://en.wikipedia.org/wiki/Table_of_spherical_harmonics +#define k01 0.28209479177387814 // Math.sqrt( 1/Math.PI)/2 +#define k02 0.4886025119029199 // Math.sqrt( 3/Math.PI)/2 +#define k03 1.0925484305920792 // Math.sqrt( 15/Math.PI)/2 +#define k04 0.31539156525252005 // Math.sqrt( 5/Math.PI)/4 +#define k05 0.5462742152960396 // Math.sqrt( 15/Math.PI)/4 +#define k06 0.5900435899266435 // Math.sqrt( 70/Math.PI)/8 +#define k07 2.890611442640554 // Math.sqrt(105/Math.PI)/2 +#define k08 0.4570457994644658 // Math.sqrt( 42/Math.PI)/8 +#define k09 0.3731763325901154 // Math.sqrt( 7/Math.PI)/4 +#define k10 1.445305721320277 // Math.sqrt(105/Math.PI)/4 + +#define k11 2.5033429417967046 // Math.sqrt( 35/Math.PI) * 3 / 4 +#define k12 1.7701307697799304 // Math.sqrt(35/2/Math.PI) * 3 / 4 +#define k13 0.9461746957575601 // Math.sqrt( 5/Math.PI) * 3 / 4 +#define k14 0.6690465435572892 // Math.sqrt( 5/2/Math.PI) * 3 / 4 +#define k15 0.10578554691520431 // Math.sqrt( 1/Math.PI) * 3 / 16 +#define k16 0.47308734787878004 // Math.sqrt( 5/Math.PI) * 3 / 8 +#define k17 0.6258357354491761 // Math.sqrt( 35/Math.PI) * 3 / 16 + +#define k18 2.5033429417967046 // Math.sqrt( 35/Math.PI) * 3 / 4 +#define k19 1.7701307697799304 // Math.sqrt(35/2/Math.PI) * 3 / 4 +#define k20 0.9461746957575601 // Math.sqrt( 5/Math.PI) * 3 / 4 +#define k21 0.6690465435572892 // Math.sqrt( 5/2/Math.PI) * 3 / 4 +#define k22 0.10578554691520431 // Math.sqrt( 1/Math.PI) * 3 / 16 +#define k23 0.47308734787878004 // Math.sqrt( 5/Math.PI) * 3 / 8 +#define k24 0.6258357354491761 // Math.sqrt( 35/Math.PI) * 3 / 16 + +// Y_l_m(s), where l is the band and m the range in [-l..l] +float SH( in int l, in int m, in vec3 s ) +{ + vec3 n = s.zxy; + + //---------------------------------------------------------- + if( l==0 ) return k01; + //---------------------------------------------------------- + if( l==1 && m==-1 ) return -k02*n.y; + if( l==1 && m== 0 ) return k02*n.z; + if( l==1 && m== 1 ) return -k02*n.x; + //---------------------------------------------------------- + if( l==2 && m==-2 ) return k03*n.x*n.y; + if( l==2 && m==-1 ) return -k03*n.y*n.z; + if( l==2 && m== 0 ) return k04*(3.0*n.z*n.z-1.0); + if( l==2 && m== 1 ) return -k03*n.x*n.z; + if( l==2 && m== 2 ) return k05*(n.x*n.x-n.y*n.y); + //---------------------------------------------------------- + if( l==3 && m==-3 ) return -k06*n.y*(3.0*n.x*n.x-n.y*n.y); + if( l==3 && m==-2 ) return k07*n.z*n.y*n.x; + if( l==3 && m==-1 ) return -k08*n.y*(5.0*n.z*n.z-1.0); + if( l==3 && m== 0 ) return k09*n.z*(5.0*n.z*n.z-3.0); + if( l==3 && m== 1 ) return -k08*n.x*(5.0*n.z*n.z-1.0); + if( l==3 && m== 2 ) return k10*n.z*(n.x*n.x-n.y*n.y); + if( l==3 && m== 3 ) return -k06*n.x*(n.x*n.x-3.0*n.y*n.y); + //---------------------------------------------------------- + + return 0.0; +} + +// unrolled version of the above +float SH_0_0( in vec3 s ) { vec3 n = s.zxy; return k01; } + +float SH_1_0( in vec3 s ) { vec3 n = s.zxy; return -k02*n.y; } +float SH_1_1( in vec3 s ) { vec3 n = s.zxy; return k02*n.z; } +float SH_1_2( in vec3 s ) { vec3 n = s.zxy; return -k02*n.x; } + +float SH_2_0( in vec3 s ) { vec3 n = s.zxy; return k03*n.x*n.y; } +float SH_2_1( in vec3 s ) { vec3 n = s.zxy; return -k03*n.y*n.z; } +float SH_2_2( in vec3 s ) { vec3 n = s.zxy; return k04*(3.0*n.z*n.z-1.0); } +float SH_2_3( in vec3 s ) { vec3 n = s.zxy; return -k03*n.x*n.z; } +float SH_2_4( in vec3 s ) { vec3 n = s.zxy; return k05*(n.x*n.x-n.y*n.y); } + +float SH_3_0( in vec3 s ) { vec3 n = s.zxy; return -k06*n.y*(3.0*n.x*n.x-n.y*n.y); } +float SH_3_1( in vec3 s ) { vec3 n = s.zxy; return k07*n.z*n.y*n.x; } +float SH_3_2( in vec3 s ) { vec3 n = s.zxy; return -k08*n.y*(5.0*n.z*n.z-1.0); } +float SH_3_3( in vec3 s ) { vec3 n = s.zxy; return k09*n.z*(5.0*n.z*n.z-3.0); } +float SH_3_4( in vec3 s ) { vec3 n = s.zxy; return -k08*n.x*(5.0*n.z*n.z-1.0); } +float SH_3_5( in vec3 s ) { vec3 n = s.zxy; return k10*n.z*(n.x*n.x-n.y*n.y); } +float SH_3_6( in vec3 s ) { vec3 n = s.zxy; return -k06*n.x*(n.x*n.x-3.0*n.y*n.y); } + +float SH_4_0( in vec3 s ) { vec3 n = s.zxy; return k11 * (n.x*n.y * (n.x*n.x - n.y*n.y)); } +float SH_4_1( in vec3 s ) { vec3 n = s.zxy; return -k12 * (3.0*n.x*n.x - n.y*n.y) * n.y * n.z; } +float SH_4_2( in vec3 s ) { vec3 n = s.zxy; return k13 * (n.x*n.y * (7.0*n.z*n.z-dot(n,n)) ); } +float SH_4_3( in vec3 s ) { vec3 n = s.zxy; return -k14 * (n.z*n.y * (7.0*n.z*n.z-3.0*dot(n,n)) ); } +float SH_4_4( in vec3 s ) { vec3 n = s.zxy; + float z2 = n.z*n.z, r2 = dot(n, n); return k15 * (35.0 * z2*z2 - 30.0 * z2*r2 + 3.0 * r2*r2); } +float SH_4_5( in vec3 s ) { vec3 n = s.zxy; return -k14 * (n.z*n.x * (7.0*n.z*n.z-3.0*dot(n,n)) ); } +float SH_4_6( in vec3 s ) { vec3 n = s.zxy; return k16 * ( (n.x*n.x-n.y*n.y)*(7.0*n.z*n.z-dot(n,n)) ); } +float SH_4_7( in vec3 s ) { vec3 n = s.zxy; return -k12 * n.x*n.z*(n.x*n.x-3.0*n.y*n.y); } +float SH_4_8( in vec3 s ) { vec3 n = s.zxy; + float x2 = n.x*n.x, y2 = n.y*n.y; return k17 * (x2 * (x2-3.0*y2) - y2*(3.0*x2 - y2)); } + +vec3 map( in vec3 p ) +{ + vec3 p00 = p - vec3( 0.00, 3.0, 0.0); + vec3 p01 = p - vec3(-1.25, 2.0, 0.0); + vec3 p02 = p - vec3( 0.00, 2.0, 0.0); + vec3 p03 = p - vec3( 1.25, 2.0, 0.0); + vec3 p04 = p - vec3(-2.50, 0.5, 0.0); + vec3 p05 = p - vec3(-1.25, 0.5, 0.0); + vec3 p06 = p - vec3( 0.00, 0.5, 0.0); + vec3 p07 = p - vec3( 1.25, 0.5, 0.0); + vec3 p08 = p - vec3( 2.50, 0.5, 0.0); + vec3 p09 = p - vec3(-3.75,-1.0, 0.0); + vec3 p10 = p - vec3(-2.50,-1.0, 0.0); + vec3 p11 = p - vec3(-1.25,-1.0, 0.0); + vec3 p12 = p - vec3( 0.00,-1.0, 0.0); + vec3 p13 = p - vec3( 1.25,-1.0, 0.0); + vec3 p14 = p - vec3( 2.50,-1.0, 0.0); + vec3 p15 = p - vec3( 3.75,-1.0, 0.0); + + vec3 p16 = p - vec3(-5.00,-2.7, 0.0); + vec3 p17 = p - vec3(-3.75,-2.7, 0.0); + vec3 p18 = p - vec3(-2.50,-2.7, 0.0); + vec3 p19 = p - vec3(-1.25,-2.7, 0.0); + vec3 p20 = p - vec3( 0.00,-2.7, 0.0); + vec3 p21 = p - vec3( 1.25,-2.7, 0.0); + vec3 p22 = p - vec3( 2.50,-2.7, 0.0); + vec3 p23 = p - vec3( 3.75,-2.7, 0.0); + vec3 p24 = p - vec3( 5.00,-2.7, 0.0); + + float r, d; vec3 n, s, res; + + #ifdef SHOW_SPHERES + #define SHAPE (vec3(d-0.35, -1.0+2.0*clamp(0.5 + 16.0*r,0.0,1.0),d)) + #else + #define SHAPE (vec3(d-abs(r), sign(r),d)) + #endif + d=length(p00); n=p00/d; r = SH_0_0( n ); s = SHAPE; res = s; + d=length(p01); n=p01/d; r = SH_1_0( n ); s = SHAPE; if( s.xmaxd ) break; + vec3 res = map( ro+rd*t ); + h = res.x; + m = res.yz; + t += h*0.3; + } + if( t-0.5 ) + { + // geometry + vec3 pos = ro + tmat.x*rd; + vec3 nor = calcNormal(pos); + vec3 ref = reflect( rd, nor ); + + // material + vec3 mate = 0.5*mix( vec3(1.0,0.2,0.15), vec3(0.15,0.7,1.0), tmat.y ); + + float occ = clamp( 2.0*tmat.z, 0.0, 1.0 ); + float sss = pow( clamp( 1.0 + dot(nor,rd), 0.0, 1.0 ), 1.0 ); + + // lights + vec3 lin = 2.5*occ*vec3(1.0,1.00,1.00)*(0.6+0.4*nor.y); + lin += 1.0*sss*vec3(1.0,0.95,0.70)*occ; + + // surface-light interacion + col = mate.xyz * lin; + } + + // gamma + col = pow( clamp(col,0.0,1.0), vec3(0.4545) ); + tot += col; + } + tot /= float(AA*AA); + fragColor = vec4( tot, 1.0 ); +} diff --git a/DuShaders/0-5OrdersSphericalHarmonics.ini b/DuShaders/0-5OrdersSphericalHarmonics.ini new file mode 100644 index 0000000..6435472 --- /dev/null +++ b/DuShaders/0-5OrdersSphericalHarmonics.ini @@ -0,0 +1,12 @@ +shader_frag = $Name.glsl +channels_count = 1 +iChannel0_type = London + +window_width = 1920 +window_height = 1080 + +recording = true +record_start = 1 +record_end = 600 +record_video = true + diff --git a/ShaderOfWeek/NotebookDrawing.cmd b/ShaderOfWeek/NotebookDrawing.cmd new file mode 100644 index 0000000..2c094e9 --- /dev/null +++ b/ShaderOfWeek/NotebookDrawing.cmd @@ -0,0 +1 @@ +"../DuEngine/x64/Release/DuEngine.exe" %~n0.ini diff --git a/ShaderOfWeek/NotebookDrawing.glsl b/ShaderOfWeek/NotebookDrawing.glsl new file mode 100644 index 0000000..036f13e --- /dev/null +++ b/ShaderOfWeek/NotebookDrawing.glsl @@ -0,0 +1,114 @@ +// created by florian berger (flockaroo) - 2016 +// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. + +// trying to resemle some hand drawing style + + +#define SHADERTOY +#ifdef SHADERTOY +#define Res0 iChannelResolution[0].xy +#define Res1 iChannelResolution[1].xy +#else +#define Res0 textureSize(iChannel0,0) +#define Res1 textureSize(iChannel1,0) +#define iResolution Res0 +#endif + +#define Res iResolution.xy + +#define randSamp iChannel1 +#define colorSamp iChannel0 + + +vec4 getRand(vec2 pos) +{ + return textureLod(iChannel1,pos/Res1/iResolution.y*1080., 0.0); +} + +vec4 getCol(vec2 pos) +{ + // take aspect ratio into account + vec2 uv=((pos-Res.xy*.5)/Res.y*Res0.y)/Res0.xy+.5; + vec4 c1=texture(iChannel0,uv); + vec4 e=smoothstep(vec4(-0.05),vec4(-0.0),vec4(uv,vec2(1)-uv)); + c1=mix(vec4(1,1,1,0),c1,e.x*e.y*e.z*e.w); + float d=clamp(dot(c1.xyz,vec3(-.5,1.,-.5)),0.0,1.0); + vec4 c2=vec4(.7); + return min(mix(c1,c2,1.8*d),.7); +} + +vec4 getColHT(vec2 pos) +{ + return smoothstep(.95,1.05,getCol(pos)*.8+.2+getRand(pos*.7)); +} + +float getVal(vec2 pos) +{ + vec4 c=getCol(pos); + return pow(dot(c.xyz,vec3(.333)),1.)*1.; +} + +vec2 getGrad(vec2 pos, float eps) +{ + vec2 d=vec2(eps,0); + return vec2( + getVal(pos+d.xy)-getVal(pos-d.xy), + getVal(pos+d.yx)-getVal(pos-d.yx) + )/eps/2.; +} + +#define AngleNum 3 + +#define SampNum 16 +#define PI2 6.28318530717959 + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 pos = fragCoord+4.0*sin(iTime*1.*vec2(1,1.7))*iResolution.y/400.; + vec3 col = vec3(0); + vec3 col2 = vec3(0); + float sum=0.; + for(int i=0;i