From a48dea9e48beb2932aefb41daefbaa565533f24d Mon Sep 17 00:00:00 2001 From: Thorsten Renk Date: Tue, 11 Aug 2015 16:28:32 +0300 Subject: [PATCH] Lightning for AW with ALS support - work in progress --- Effects/cloud.eff | 24 +++++ Effects/rain-layer.eff | 58 +++++++---- Environment/environment.xml | 9 ++ Models/Weather/lightning.rgb | Bin 27837 -> 26720 bytes Models/Weather/lightning1.xml | 54 ++++++++++ Nasal/local_weather/compat_layer.nas | 48 +++++++++ Nasal/local_weather/local_weather.nas | 10 ++ .../local_weather/weather_tile_management.nas | 97 ++++++++++++++++++ Nasal/local_weather/weather_tiles.nas | 30 +++++- Shaders/3dcloud-ALS.vert | 15 +++ Shaders/model-interior-ALS-detailed.vert | 9 +- ...er-lightfield.frag => rain-layer-ALS.frag} | 0 ...er-lightfield.vert => rain-layer-ALS.vert} | 27 +++-- 13 files changed, 346 insertions(+), 35 deletions(-) create mode 100644 Models/Weather/lightning1.xml rename Shaders/{rain-layer-lightfield.frag => rain-layer-ALS.frag} (100%) rename Shaders/{rain-layer-lightfield.vert => rain-layer-ALS.vert} (88%) diff --git a/Effects/cloud.eff b/Effects/cloud.eff index 8e2d830e7..094a53682 100644 --- a/Effects/cloud.eff +++ b/Effects/cloud.eff @@ -13,6 +13,10 @@ /environment/moonlight /environment/air-pollution-norm /environment/visibility-m + /environment/lightning/flash + /environment/lightning/lightning-pos-x + /environment/lightning/lightning-pos-y + /environment/lightning/lightning-range @@ -118,6 +122,26 @@ float visibility + + flash + float + flash + + + lightning_pos_x + float + lightning-pos-x + + + lightning_pos_y + float + lightning-pos-y + + + lightning_range + float + lightning-range + diff --git a/Effects/rain-layer.eff b/Effects/rain-layer.eff index e9835076a..aa834df4d 100644 --- a/Effects/rain-layer.eff +++ b/Effects/rain-layer.eff @@ -4,15 +4,13 @@ - - /sim/rendering/clouds3d-vis-range - - - /rendering/scene/scattering - - - /environment/terminator-relative-position-m - + /sim/rendering/clouds3d-vis-range + /rendering/scene/scattering + /environment/terminator-relative-position-m + /environment/lightning/flash + /environment/lightning/lightning-pos-x + /environment/lightning/lightning-pos-y + /environment/lightning/lightning-range @@ -60,8 +58,8 @@ clamp--> - Shaders/rain-layer-lightfield.vert - Shaders/rain-layer-lightfield.frag + Shaders/rain-layer-ALS.vert + Shaders/rain-layer-ALS.frag baseTexture @@ -78,12 +76,32 @@ float scattering - - terminator - float - terminator + + terminator + float + terminator - true + + flash + float + flash + + + lightning_pos_x + float + lightning-pos-x + + + lightning_pos_y + float + lightning-pos-y + + + lightning_range + float + lightning-range + + @@ -149,10 +167,10 @@ float scattering - - terminator - float - terminator + + terminator + float + terminator true diff --git a/Environment/environment.xml b/Environment/environment.xml index 000791e02..58ebd3eae 100644 --- a/Environment/environment.xml +++ b/Environment/environment.xml @@ -440,6 +440,15 @@ 1.0 + + + + 0.0 + 0.0 + 0.0 + 0.0 + + 0.015 diff --git a/Models/Weather/lightning.rgb b/Models/Weather/lightning.rgb index b5236e53bb7eaa04931d30d2b91b95787655ec59..91376cf99338dcb05ff75494d60cc88cda40e765 100644 GIT binary patch delta 5466 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 EAFMA9@Bjb+ delta 6552 zcmZXY33yahmd8)kt9n&0c~DZMs3at0BV-2xgs=pH?8v?oHbdB#MiF`t5kn6!1FPyVke_nv$1Ip_bs z=f3j&SA0*ujC})i7rCKMWXwY%qc4Jv zBBO?hj9f1=;<(6gf*)>+3@a5GdPL;= zy(0bp3J9v-?IM*=fkKhK1XuARm@U$0pGfcj0DVMyk#+f_B0b*&St31tF4FyF5ELmZ z5-FW3QnE&*_^3$He}f((g{wsh*tgs7Kz)fw{z8$ils4}&$PmfBO(f?9kSdbBLL}>1 zkuGfBWtm9k2cS$OgCIJ82>70EKqrwjDwfJ7sp~+pNc`U^n|8(ZIiGo1Pv@e1J8hV zXkaE9fbQzAKm{7Og-8bxT@{g4k?p{n(7+2I7Y!^z1HXj-KZ0>+;4H{S1C40lMG!y( z1l|j7%h5x53L3z!$KCM%HDH6XS~Rc?4V*v&uLArQ)uDmA&;ZGGtN)J2Bs6dU4ZHz} zG7l%Y_rgC%EoU$qKzv#7o>htlS^*npvT??v0Q=6f;2)u;SE2!^N+Xce{h%8f*aiRJ zfQ9h?DOe2upMm3O;7{=1@j8S+nN|_$$|pe*8X%zMJK-P0Wt42`Uig0p3`7HDyXeng z6dEvSfXdZ%MFY#xz+>?LKIn%A9sqtcFb54hf(A%nHZ;ygs5Q*bx&aN`s{H>RAq+qR zP%-T}G;kF_#gyr2;20W!|4CWs0GkQ)iSgKt!{NBjXrKWNybP$wm})ez1`SY^k?#UD zF=8|t;1~}(0{<4QxOIzXJ{$xE>AMiU#;Q7biKZ(7*){K?Bg#g)(=c4K(Ez%c{}RYY15{)#G|y$toE~TZ?rZAM zz()9=c^CYD1?HoH<7nV(Kz37cIOPsBfRoAX(E!v;{5v$T8x5R?e>faRrN%x8|K9ZPb=RNhMG_{aXXlF-=a_X)wh= z*XbHXU-tJlRs(ga&P#zBsgrAw>bPd4HoA$9E3O5r&h&3xbFC^G^fl-j^?R*ynv~j> zXa+i{j`ULvHOgy_)R}(Qc?}@XoM{*DpTjpTwi1&IIs+v~0m+gDG;b6wDL}VVRPT%K z9^9Ono*s|KqA@GF*R|q~xK6}zBhiQ>wjGk4Q8yBC9oLPzb|etp5s5_OG5+J9FWr}E z_C}8nx+{~BSUehInImG0W4X5L+KwZZ6_mZU*p}_+)3wxn#Bv)W>Maqo;-;eGi9x%g z5!bfa*b?k8WMPw7-e*t}mMx8z&0jlo0s~8I$Fdq6*XQ~y^M1$P(FV&6U>K7I%Zliu zgGou5n4TdGw(Ux*E+8RXvN$9@%V!p)tm=wgnl$2B*IJUWgVJQR89F!-AC~6rl$y*2 zu~OI?6H6zs-|9t|tn18>*os`{*aZIxI|>4_vn^0YIiPIlnBT_MmNwW{GBIJz!`6rA z&z3E=ONwmI=(Pp4oqqPy0^J(hAa!uO6_{?d9V#6nlD{qZveU%Wgq4b^-CoB@oOKZ= zOhjg8d|`INP9x%E+08akwbn|nj>IT?kp0=$Z{CdG)Gc9UYL2Yb$3X%UC-P4}uFgaX z)&}U&BKpme)a3zU$~3Q}-X6fTvl*YZN58Z;m(wzW%9!6=P1|lItQ6Cnp3jKu_|4h$ z#<_V2 z#bgQ!i~aThGqtcj&=A4fYlU4|^KIch;T^D|N7US1RKn0pMJLsHlKFXYcaD-*$NP$p zT8W5bhL!XTa$M2Yx{~{>M9em6rJ1P*_3+@sns&fdPb)Z#Wac;HO7~j{H)K92?SbPC zWt(tvo!MQM7i#lso5#wKuWnY}y#SM%?t3-5koly0F?n|CaZlTyPxL5-20EeNeB9%Z z>fAB)JqzecUU(1oYzj58KON5WDlcN?-13IdHgCi-|6ZOOQaRGEOt9A`dy9@Io5o&w zp~h?}^Ud*@6TJ@fK~$FA$l0_wp)`r?s&zlqx)T~!*j9Vlr$-k5LWj~L7?r4RtuNQC z?tPmtXg=+o7eaErh_BK_`z#N$Ge&m6B>H5i?p`0U54bk+-zQ{sjS}&AF?_x!FJ6tvGQxa zFLXN46jfJLCWL0R`Uxv&E)F?nd!5!c>#i?KvSgdyPUK>aUVqw7uusA^lZF;2HFM7^ zIn3NKw5e^zGS09rNjezNo6=-sM%)-Q~@GuY@&%o?59VXJmaJLGJ2>6NZlfAi>##1b@DMyFlZqHj6c z#>93Vo$NMdb&&?6mD%pb*B$xnquWM8Q3G#5o~-l|Z?lH3UyoT8O3+7Jt(YmhA>NS^ zQbA%@0oskk>Nk^aIP0ai+p045*n;+`mQcLnh~F_4V~>Ok;)oPxn>WYix1%c1skO1W zWv-4r9Wq4dN})M7u9!x?RjFtz+~sliYIANJUle9zb!nM1pvmSPI7n!3YbL` z_F8tdxA}HLPI8j71)H|Txf2^hduY7r6YI>$iD@0TD_LI6iQcoa%%zFPgLZy)e1*An zQb}@?%0L6-5`AFOA-*~lw;eOXCKqs699pW@Z`I^GL;G<%^W+(mJf$QFqekkl+U_@H ztsRlb9Y>Fwvs1c+y%`nkr73&tXf)n%{DN6JHTOCVL>bXCdivNmbzaw)Rk`Er*H;dl z+;M2YhKc7_aLdJb4dmnsVZp3JCuuirt8GVSuKWC9b9h>|!;6_#nTcObI~y#V`G=RD zHfyGrw%g{Fmq~iJ-`qR>Av;>}&iQ+uGLvVNw1;<>#z8f`*)20p*i{?e+VJEDruWR! zu%32ryl&=6JCgs@nkSw&9cL9L>q{siA!NU)n)Oh~8SrY;lTZC%KABbGQ9}!`Oj^yZ zQ14S8AA9|NOJ7X78LhYT1e-&Z#*u zXGxA7udUnk&FQP({O0IH6}k7~sr?{Klb}rnP0`$A&dw;mpk93c`ESjua|@DqyHVOL z*u64$dpP1`58w9T!&gk}ye=u*D7@EuRPcH}R2+}byS>j2-r=S4xg%G;yR_D!lUUku ziBjm!`?cL^yYxP_2=J{7XU%U3>%nX8y{*aoVSYwf8$V+7o8XO2;Z_$-j68qYm>au> z954NVIe+7pFs}k!Gi#5U>udA>HnFsJb65{@t9{_K`LEiXkk&}MdStBhg<{ZT9yrXerk--jaU*Z|~W(_P&;Vyy^1BOtn=( zz7|{c$0uQVy~s2#Z0Ola6qe+!K3a_cqPotZ%KB{US8YFVJR11(0XzakGYo;&$ zMSmJ1+10)9(ljUCiPD(3Q_v8^Qb*k~;QfsJ>2l-u2;}M8j%C~>jlJ7k*AAbb&i^HI zon)=wTR?b~GG$*2|i~iceKxt;NChjxOEN$%(!?Qhn^_hI(H&-I!{U+m(dL`0pN#9z$ J{IuIS@;{G5lOzBD diff --git a/Models/Weather/lightning1.xml b/Models/Weather/lightning1.xml new file mode 100644 index 000000000..3df51f1f0 --- /dev/null +++ b/Models/Weather/lightning1.xml @@ -0,0 +1,54 @@ + + + + lightning.ac + + + rect + Effects/rain-layer + + + + 0.0 + 0.0 + -1.2 + + + + + scale + 700.0 + 700.0 + 1000.0 + + + + material + + 0.9 + 0.9 + 1.0 + + + + + select + + + /environment/lightning/flash + 0.0 + + + + + + billboard + false + + + + false + + + + diff --git a/Nasal/local_weather/compat_layer.nas b/Nasal/local_weather/compat_layer.nas index 98c085849..e5ca6b228 100644 --- a/Nasal/local_weather/compat_layer.nas +++ b/Nasal/local_weather/compat_layer.nas @@ -618,6 +618,54 @@ model.getNode("load", 1).remove(); } +########################################################### +# place a model with control properties +########################################################### + +var place_model_controlled = func(string, path, lat, lon, alt, heading, pitch, roll) { + + + +var m = props.globals.getNode("models", 1); + for (var i = 0; 1; i += 1) + if (m.getChild("model", i, 0) == nil) + break; +var model = m.getChild("model", i, 1); + + +setprop("/local-weather/"~string~"/latitude-deg", lat); +setprop("/local-weather/"~string~"/longitude-deg", lon); +setprop("/local-weather/"~string~"/elevation-ft", alt); +setprop("/local-weather/"~string~"/heading-deg", heading); +setprop("/local-weather/"~string~"/pitch-deg", pitch); +setprop("/local-weather/"~string~"/roll-deg", roll); + + + +var cmodel = props.globals.getNode("/local-weather/"~string, 1); +var latN = cmodel.getNode("latitude-deg",1); +var lonN = cmodel.getNode("longitude-deg",1); +var altN = cmodel.getNode("elevation-ft",1); +var headN = cmodel.getNode("heading-deg",1); +var pitchN = cmodel.getNode("pitch-deg",1); +var rollN = cmodel.getNode("roll-deg",1); + + + +model.getNode("path", 1).setValue(path); +model.getNode("latitude-deg-prop", 1).setValue(latN.getPath()); +model.getNode("longitude-deg-prop", 1).setValue(lonN.getPath()); +model.getNode("elevation-ft-prop", 1).setValue(altN.getPath()); +model.getNode("heading-deg-prop", 1).setValue(headN.getPath()); +model.getNode("pitch-deg-prop", 1).setValue(pitchN.getPath()); +model.getNode("roll-deg-prop", 1).setValue(rollN.getPath()); +model.getNode("tile-index",1).setValue(0); +model.getNode("load", 1).remove(); + + +#return model; +} + diff --git a/Nasal/local_weather/local_weather.nas b/Nasal/local_weather/local_weather.nas index 16fbe6993..d48c616cf 100644 --- a/Nasal/local_weather/local_weather.nas +++ b/Nasal/local_weather/local_weather.nas @@ -1667,6 +1667,7 @@ setprop(lw~"buffer-loop-flag",0); setprop(lw~"housekeeping-loop-flag",0); setprop(lw~"convective-loop-flag",0); setprop(lw~"shadow-loop-flag",0); +setprop(lw~"thunderstorm-loop-flag",0); weather_dynamics.convective_loop_kill_flag = 1; # long-running loop needs a different scheme to end @@ -1731,6 +1732,7 @@ settimer ( func { setsize(alt_min_array,0); setsize(alt_mean_array,0); setsize(weather_dynamics.cloudShadowArray,0); + setsize(local_weather.thunderstormArray,0); setsize(weather_dynamics.cloudShadowCandidateArray,0); setsize(weather_dynamics.tile_convective_altitude,0); setsize(weather_dynamics.tile_convective_strength,0); @@ -4052,6 +4054,14 @@ if (local_weather.cloud_shadow_flag == 1) # weather_tile_management.watchdog_loop(); +# start thunderstorm management + +setprop(lw~"thunderstorm-loop-flag",1); + +local_weather.place_model_controlled("lightning", "Models/Weather/lightning1.xml", lat, lon, 0.0, 0.0, 0.0, 0.0); + +local_weather.thunderstorm_management_loop(); + } diff --git a/Nasal/local_weather/weather_tile_management.nas b/Nasal/local_weather/weather_tile_management.nas index 1d1c15dae..2d37d831f 100644 --- a/Nasal/local_weather/weather_tile_management.nas +++ b/Nasal/local_weather/weather_tile_management.nas @@ -17,6 +17,8 @@ # remove_impostors to delete a ring of impostors to mimick distant clouds # create_impostors to create a ring of impostors to mimick distant clouds # shadow_management_loop to manage cloud shadow information +# thunderstorm_management_loop to manage information on thunderstorm position +# lightning_strike to get the timing for a lightning strike to the property tree # watchdog loop (debug helping structure) # calc_geo to get local Cartesian geometry for latitude conversion # get_lat to get latitude from Cartesian coordinates @@ -1261,6 +1263,86 @@ if (local_weather.debug_output_flag == 1) weather_tiles.create_impostor_ring(lat, lon, alt, alpha, type, n); } +################################## +# Thunderstorm positon management +################################## + +var thunderstorm_management_loop = func { + +if (local_weather.local_weather_running_flag == 0) {return;} + +# compute some general-purpose stuff for the loop + +var eyeLat = lwObserverLat; +var eyeLon = lwObserverLon; + +var n = size(thunderstormArray); + +#print("We have ",n," storms."); + +for (var i = 0; i < n; i=i+1) + { + var tstorm = thunderstormArray[i]; + + var rn = rand(); + #if (i == 0) {rn = 0;} else {rn = 1;} + if (rn < tstorm.strength) + { + #print("Lightning strike storm ", i,"!"); + + var diffx = -(tstorm.lat - eyeLat) * local_weather.lat_to_m; + var diffy = (tstorm.lon - eyeLon) * local_weather.lon_to_m ; + var offset_x = -3000.0 + rand() * 6000.0; + var offset_y = -3000.0 + rand() * 6000.0; + + var dist = math.sqrt(diffx * diffx + diffy * diffy) ; + + setprop("/environment/lightning/lightning-pos-x", diffx + offset_x); + setprop("/environment/lightning/lightning-pos-y", diffy + offset_y); + setprop("/environment/lightning/lightning-range", tstorm.size); + setprop("/local-weather/lightning/latitude-deg", tstorm.lat - offset_x * local_weather.m_to_lat); + setprop("/local-weather/lightning/longitude-deg", tstorm.lon + offset_y * local_weather.m_to_lon); + setprop("/local-weather/lightning/altitude-ft", tstorm.alt); + lightning_strike(); + + if (dist > 50000.0) + { + thunderstormArray = delete_from_vector(thunderstormArray,i); + print("Removing storm ", i); + break; + } + } + + + } + + +if (getprop(lw~"thunderstorm-loop-flag") ==1) {settimer( func {thunderstorm_management_loop()}, 1.0);} +} + +var lightning_strike = func { + +var rn = rand(); + +var repeat = 1; + +if (rn > 0.5) {repeat = 2;} + +var duration = 0.1 + 0.1 * rand(); +var strength = 0.5 + 1.0 * rand(); + +setprop("/environment/lightning/flash", strength); +settimer( func{ setprop("/environment/lightning/flash", 0.0);}, duration); + +var duration1 = 0.1 + 0.1 * rand(); + +if (repeat == 2) + { + settimer( func{ setprop("/environment/lightning/flash", strength);}, duration + 0.1); + settimer( func{ setprop("/environment/lightning/flash", 0.0);}, duration + 0.1 + duration1); + } + +} ############################### # Cloud shadow management @@ -1528,6 +1610,7 @@ var cloud_view_distance = getprop(lw~"config/clouds-visible-range-m"); var modelArrays = []; var active_tile_list = []; +var thunderstormArray = []; # a bunch of variables to be updated per frame used by different # routines, managed by the housekeeping loop @@ -1543,6 +1626,8 @@ var lwTileIndex = 0; # hashes to manage clouds in scenery or in the buffer ##################################################### + + var cloudBufferArray = []; @@ -1618,6 +1703,18 @@ var cloudShadow = { }, }; +var thunderstormHash = { + new: func (lat, lon, alt, size, strength) { + var t = {parents: [thunderstormHash] }; + t.lat = lat; + t.lon = lon; + t.alt = alt; + t.size = size; + t.strength = strength; + return t; + }, +}; + var cloudSceneryArray = []; var n_cloudSceneryArray = 0; diff --git a/Nasal/local_weather/weather_tiles.nas b/Nasal/local_weather/weather_tiles.nas index e0b9709d4..9ff43d635 100644 --- a/Nasal/local_weather/weather_tiles.nas +++ b/Nasal/local_weather/weather_tiles.nas @@ -1720,7 +1720,7 @@ local_weather.convective_size_bias = 0.3 + rand() * 0.3; # and specify the atmosphere - local_weather.set_atmosphere_ipoint(blat, blon, vis + 12000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); + local_weather.set_atmosphere_ipoint(blat, blon, vis + 12000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); var rn = rand(); @@ -4295,18 +4295,34 @@ x = 2.0 * (rand()-0.5) * 12000; y = 2.0 * (rand()-0.5) * 12000; if (rand() > 0.6) - {create_medium_thunderstorm(lat +get_lat(x,y,phi), lon + get_lon(x,y,phi), alt, alpha);} + { + create_medium_thunderstorm(lat +get_lat(x,y,phi), lon + get_lon(x,y,phi), alt, alpha); + var ts = local_weather.thunderstormHash.new (lat +get_lat(x,y,phi), lon + get_lon(x,y,phi), alt, 3000.0, 0.2); + append(local_weather.thunderstormArray,ts); + } else - {create_small_thunderstorm(lat +get_lat(x,y,phi), lon + get_lon(x,y,phi), alt, alpha);} + { + create_small_thunderstorm(lat +get_lat(x,y,phi), lon + get_lon(x,y,phi), alt, alpha); + var ts = local_weather.thunderstormHash.new (lat +get_lat(x,y,phi), lon + get_lon(x,y,phi), alt, 1000.0, 0.15); + append(local_weather.thunderstormArray,ts); + } if (rand() > 0.5) # we do a second thunderstorm { x = 2.0 * (rand()-0.5) * 12000; y = 2.0 * (rand()-0.5) * 12000; if (rand() > 0.8) - {create_medium_thunderstorm(lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt, alpha);} + { + create_medium_thunderstorm(lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt, alpha); + var ts = local_weather.thunderstormHash.new (lat +get_lat(x,y,phi), lon + get_lon(x,y,phi), alt, 3000.0, 0.2); + append(local_weather.thunderstormArray,ts); + } else - {create_small_thunderstorm(lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt, alpha);} + { + create_small_thunderstorm(lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt, alpha); + var ts = local_weather.thunderstormHash.new (lat +get_lat(x,y,phi), lon + get_lon(x,y,phi), alt, 1000.0, 0.15); + append(local_weather.thunderstormArray,ts); + } } # the convective layer @@ -4315,6 +4331,10 @@ var strength = 0.10; var n = int(4000 * strength) * 0.5; local_weather.cumulus_exclusion_layer(lat, lon, alt, n, 20000.0, 20000.0, alpha, 0.3,2.5 , size(elat), elat, elon, erad); +# some additional cloud cover + +create_4_8_sstratus_domains(lat, lon, alt,alpha); + # some turbulence in the convection layer diff --git a/Shaders/3dcloud-ALS.vert b/Shaders/3dcloud-ALS.vert index 43f522d6f..6c273e14d 100644 --- a/Shaders/3dcloud-ALS.vert +++ b/Shaders/3dcloud-ALS.vert @@ -13,6 +13,10 @@ uniform float cloud_self_shading; uniform float visibility; uniform float moonlight; uniform float air_pollution; +uniform float flash; +uniform float lightning_pos_x; +uniform float lightning_pos_y; +uniform float lightning_range; attribute vec3 usrAttr1; attribute vec3 usrAttr2; @@ -171,10 +175,21 @@ void main(void) } + + gl_FrontColor.rgb = intensity * shade * normalize(mix(light_diffuse.rgb, shadedFogColor, smoothstep(0.1,0.4, (1.0 - shade) ))) ; + // lightning + vec2 lightningRelVector = relVector.xy - vec2(lightning_pos_x, lightning_pos_y); + float rCoord = length(lightningRelVector); + + + float rn = 0.5 + 0.5 * fract(gl_Color.x); + gl_FrontColor.rgb += flash * vec3 (0.43, 0.57, 1.0) * (1.0 - smoothstep(lightning_range, 5.0 * lightning_range, rCoord)) * rn; + // fading of cloudlets + if ((fogCoord > (0.9 * detail_range)) && (fogCoord > center_dist) && (shade_factor < 0.7)) { // cloudlet is almost at the detail range, so fade it out. gl_FrontColor.a = 1.0 - smoothstep(0.9 * detail_range, detail_range, fogCoord); diff --git a/Shaders/model-interior-ALS-detailed.vert b/Shaders/model-interior-ALS-detailed.vert index b2325534d..df74a60c2 100644 --- a/Shaders/model-interior-ALS-detailed.vert +++ b/Shaders/model-interior-ALS-detailed.vert @@ -230,7 +230,7 @@ else // the faster, full-day version without lightfields yprime_alt = -sqrt(2.0 * EarthRadius * hazeLayerAltitude); } -// irradiance mapping +// irradiance mapping for ambient light float ambient_irradiance_factor = 1.0; float steepness = dot(normalize(gl_Normal), vec3 (0.0, 0.0, 1.0)); @@ -253,6 +253,8 @@ else // the faster, full-day version without lightfields light_ambient = light_ambient * ambient_irradiance_factor; +// residual ambience - comes with its own irradiance map + vec3 residual_ambience = vec3 (residual_ambience_r, residual_ambience_g, residual_ambience_b); ambient_irradiance_factor = 1.0; @@ -272,7 +274,10 @@ else // the faster, full-day version without lightfields ambient_irradiance_factor = (1.0 - ra_irradiance_map_strength) + 1.5 * ra_irradiance_map_strength * (1.0 - abs(steepness)) * (0.5 + 0.5 * forwardness); } - light_ambient.rgb += residual_ambience.rgb * ambient_irradiance_factor; + // make sure the residual ambience is only visible when it's dark enough + float residual_fraction = length(residual_ambience.rgb) / (length(light_ambient.rgb + residual_ambience.rgb) + 0.01); + + light_ambient.rgb += residual_ambience.rgb * ambient_irradiance_factor * smoothstep(0.4, 0.6, residual_fraction); // default lighting based on texture and material using the light we have just computed diff --git a/Shaders/rain-layer-lightfield.frag b/Shaders/rain-layer-ALS.frag similarity index 100% rename from Shaders/rain-layer-lightfield.frag rename to Shaders/rain-layer-ALS.frag diff --git a/Shaders/rain-layer-lightfield.vert b/Shaders/rain-layer-ALS.vert similarity index 88% rename from Shaders/rain-layer-lightfield.vert rename to Shaders/rain-layer-ALS.vert index b212a867a..b008d5553 100644 --- a/Shaders/rain-layer-lightfield.vert +++ b/Shaders/rain-layer-ALS.vert @@ -8,6 +8,10 @@ uniform float range; // From /sim/rendering/clouds3d-vis-range uniform float scattering; uniform float terminator; uniform float altitude; +uniform float flash; +uniform float lightning_pos_x; +uniform float lightning_pos_y; +uniform float lightning_range; float shade = 0.8; @@ -88,6 +92,18 @@ void main(void) gl_FrontColor = mix(backlight, gl_LightSource[0].diffuse, n); gl_FrontColor += gl_FrontLightModelProduct.sceneColor; + // two times terminator width governs how quickly light fades into shadow + float terminator_width = 200000.0; + float earthShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, yprime_alt) + 0.1; + gl_FrontColor.rgb = gl_FrontColor.rgb * earthShade; + + // lightning + vec2 lightningRelVector = relVector.xy - vec2(lightning_pos_x, lightning_pos_y); + float rCoord = length(lightningRelVector); + + gl_FrontColor.rgb += 2.0 * flash * vec3 (0.43, 0.57, 1.0) * (1.0 - smoothstep(lightning_range, 5.0 * lightning_range, rCoord)); + gl_FrontColor.rgb = clamp(gl_FrontColor.rgb,0.0,1.0); + // As we get within 100m of the sprite, it is faded out. Equally at large distances it also fades out. gl_FrontColor.a = min(smoothstep(100.0, 250.0, fogCoord), 1.0 - smoothstep(range*0.9, range, fogCoord)); gl_BackColor = gl_FrontColor; @@ -100,7 +116,7 @@ float fadeScale = 0.05 + 0.2 * log(fogCoord/1000.0); if (fadeScale < 0.05) fadeScale = 0.05; fogFactor = exp( -gl_Fog.density * 1.0 * fogCoord * fadeScale); - hazeColor = light_diffuse.xyz; + hazeColor = light_diffuse.rgb; hazeColor.x = hazeColor.x * 0.83; hazeColor.y = hazeColor.y * 0.9; hazeColor = hazeColor * scattering; @@ -109,14 +125,9 @@ float fadeScale = 0.05 + 0.2 * log(fogCoord/1000.0); intensity = length(hazeColor); hazeColor = intensity * normalize(mix(hazeColor, 2.0 * vec3 (0.55, 0.6, 0.8), (1.0-smoothstep(0.3,0.8,scattering)))); - // two times terminator width governs how quickly light fades into shadow - float terminator_width = 200000.0; - // now dim the light - float earthShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, yprime_alt) + 0.1; - hazeColor = hazeColor * earthShade; - gl_FrontColor.xyz = gl_FrontColor.xyz * earthShade; - gl_BackColor = gl_FrontColor; + hazeColor = clamp(hazeColor * earthShade, 0.0,1.0); + }