VolumetricFog.cs 148 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247
  1. //------------------------------------------------------------------------------------------------------------------
  2. // Volumetric Fog & Mist
  3. // Created by Ramiro Oliva (Kronnect)
  4. //------------------------------------------------------------------------------------------------------------------
  5. using UnityEngine;
  6. #if UNITY_EDITOR
  7. using UnityEditor;
  8. #endif
  9. using System;
  10. using System.Collections;
  11. using System.Collections.Generic;
  12. #if GAIA_PRESENT
  13. using Gaia;
  14. #endif
  15. namespace VolumetricFogAndMist {
  16. public enum FOG_PRESET {
  17. Clear = 0,
  18. Mist = 10,
  19. WindyMist = 11,
  20. LowClouds = 20,
  21. SeaClouds = 21,
  22. GroundFog = 30,
  23. FrostedGround = 31,
  24. FoggyLake = 32,
  25. Fog = 41,
  26. HeavyFog = 42,
  27. SandStorm1 = 50,
  28. Smoke = 51,
  29. ToxicSwamp = 52,
  30. SandStorm2 = 53,
  31. WorldEdge = 200,
  32. Custom = 1000
  33. }
  34. public enum SPSR_BEHAVIOUR {
  35. AutoDetectInEditor = 0,
  36. ForcedOn = 1,
  37. ForcedOff = 2
  38. }
  39. public enum TRANSPARENT_MODE {
  40. None = 0,
  41. Blend = 1
  42. }
  43. public enum COMPUTE_DEPTH_SCOPE {
  44. OnlyTreeBillboards = 0,
  45. EverythingInLayer = 1,
  46. TreeBillboardsAndTransparentObjects = 2
  47. }
  48. public enum LIGHTING_MODEL {
  49. Classic = 0,
  50. Natural = 1,
  51. SingleLight = 2
  52. }
  53. public enum SUN_SHADOWS_BAKE_MODE {
  54. Realtime = 0,
  55. Discrete = 1
  56. }
  57. public enum FOG_VOID_TOPOLOGY {
  58. Sphere = 0,
  59. Box = 1
  60. }
  61. public enum FOG_AREA_TOPOLOGY {
  62. Sphere = 1,
  63. Box = 2
  64. }
  65. public enum FOG_AREA_SORTING_MODE {
  66. DistanceToCamera = 0,
  67. Altitude = 1,
  68. Fixed = 2
  69. }
  70. public enum FOG_AREA_FOLLOW_MODE {
  71. FullXYZ = 0,
  72. RestrictToXZPlane = 1
  73. }
  74. [ExecuteInEditMode]
  75. [AddComponentMenu ("Image Effects/Rendering/Volumetric Fog & Mist")]
  76. [HelpURL ("http://kronnect.com/taptapgo")]
  77. public partial class VolumetricFog : MonoBehaviour {
  78. public const string SKW_FOG_DISTANCE_ON = "FOG_DISTANCE_ON";
  79. public const string SKW_LIGHT_SCATTERING = "FOG_SCATTERING_ON";
  80. public const string SKW_FOG_AREA_BOX = "FOG_AREA_BOX";
  81. public const string SKW_FOG_AREA_SPHERE = "FOG_AREA_SPHERE";
  82. public const string SKW_FOG_VOID_BOX = "FOG_VOID_BOX";
  83. public const string SKW_FOG_VOID_SPHERE = "FOG_VOID_SPHERE";
  84. public const string SKW_FOG_HAZE_ON = "FOG_HAZE_ON";
  85. public const string SKW_FOG_OF_WAR_ON = "FOG_OF_WAR_ON";
  86. public const string SKW_FOG_BLUR = "FOG_BLUR_ON";
  87. public const string SKW_SUN_SHADOWS = "FOG_SUN_SHADOWS_ON";
  88. public const string SKW_FOG_USE_XY_PLANE = "FOG_USE_XY_PLANE";
  89. public const string SKW_FOG_COMPUTE_DEPTH = "FOG_COMPUTE_DEPTH";
  90. const float TIME_BETWEEN_TEXTURE_UPDATES = 0.2f;
  91. const string DEPTH_CAM_NAME = "VFMDepthCamera";
  92. const string DEPTH_SUN_CAM_NAME = "VFMDepthSunCamera";
  93. const string VFM_BUILD_HINT = "VFMBuildHint9b1";
  94. static VolumetricFog _fog;
  95. public static VolumetricFog instance {
  96. get {
  97. if (_fog == null) {
  98. if (Camera.main != null)
  99. _fog = Camera.main.GetComponent<VolumetricFog> ();
  100. if (_fog == null) {
  101. foreach (Camera camera in Camera.allCameras) {
  102. _fog = camera.GetComponent<VolumetricFog> ();
  103. if (_fog != null)
  104. break;
  105. }
  106. }
  107. }
  108. return _fog;
  109. }
  110. }
  111. [HideInInspector]
  112. public bool
  113. isDirty;
  114. #region General settings
  115. [SerializeField]
  116. FOG_PRESET
  117. _preset = FOG_PRESET.Mist;
  118. public FOG_PRESET preset {
  119. get { return _preset; }
  120. set {
  121. if (value != _preset) {
  122. _preset = value;
  123. UpdatePreset ();
  124. isDirty = true;
  125. }
  126. }
  127. }
  128. [SerializeField]
  129. VolumetricFogProfile
  130. _profile;
  131. public VolumetricFogProfile profile {
  132. get { return _profile; }
  133. set {
  134. if (value != _profile) {
  135. _profile = value;
  136. if (_profile != null) {
  137. _profile.Load (this);
  138. _preset = FOG_PRESET.Custom;
  139. }
  140. isDirty = true;
  141. }
  142. }
  143. }
  144. [SerializeField]
  145. bool
  146. _useFogVolumes = false;
  147. public bool useFogVolumes {
  148. get { return _useFogVolumes; }
  149. set {
  150. if (value != _useFogVolumes) {
  151. _useFogVolumes = value;
  152. isDirty = true;
  153. }
  154. }
  155. }
  156. [SerializeField]
  157. bool
  158. _debugPass = false;
  159. public bool debugDepthPass {
  160. get { return _debugPass; }
  161. set {
  162. if (value != _debugPass) {
  163. _debugPass = value;
  164. isDirty = true;
  165. }
  166. }
  167. }
  168. [SerializeField]
  169. TRANSPARENT_MODE _transparencyBlendMode = TRANSPARENT_MODE.None;
  170. public TRANSPARENT_MODE transparencyBlendMode {
  171. get { return _transparencyBlendMode; }
  172. set {
  173. if (value != _transparencyBlendMode) {
  174. _transparencyBlendMode = value;
  175. UpdateMaterialProperties ();
  176. UpdateRenderComponents ();
  177. isDirty = true;
  178. }
  179. }
  180. }
  181. [SerializeField]
  182. float
  183. _transparencyBlendPower = 1.0f;
  184. public float transparencyBlendPower {
  185. get { return _transparencyBlendPower; }
  186. set {
  187. if (value != _transparencyBlendPower) {
  188. _transparencyBlendPower = value;
  189. UpdateMaterialProperties ();
  190. isDirty = true;
  191. }
  192. }
  193. }
  194. [SerializeField]
  195. LayerMask
  196. _transparencyLayerMask = -1;
  197. public LayerMask transparencyLayerMask {
  198. get { return _transparencyLayerMask; }
  199. set {
  200. if (_transparencyLayerMask != value) {
  201. _transparencyLayerMask = value;
  202. isDirty = true;
  203. }
  204. }
  205. }
  206. [SerializeField]
  207. LIGHTING_MODEL _lightingModel = LIGHTING_MODEL.Classic;
  208. public LIGHTING_MODEL lightingModel {
  209. get { return _lightingModel; }
  210. set {
  211. if (value != _lightingModel) {
  212. _lightingModel = value;
  213. UpdateMaterialProperties ();
  214. UpdateTexture ();
  215. isDirty = true;
  216. }
  217. }
  218. }
  219. [SerializeField]
  220. bool
  221. _computeDepth = false;
  222. public bool computeDepth {
  223. get { return _computeDepth; }
  224. set {
  225. if (value != _computeDepth) {
  226. _computeDepth = value;
  227. UpdateMaterialProperties ();
  228. isDirty = true;
  229. }
  230. }
  231. }
  232. [SerializeField]
  233. COMPUTE_DEPTH_SCOPE
  234. _computeDepthScope = COMPUTE_DEPTH_SCOPE.OnlyTreeBillboards;
  235. public COMPUTE_DEPTH_SCOPE computeDepthScope {
  236. get { return _computeDepthScope; }
  237. set {
  238. if (value != _computeDepthScope) {
  239. _computeDepthScope = value;
  240. if (_computeDepthScope == COMPUTE_DEPTH_SCOPE.TreeBillboardsAndTransparentObjects) {
  241. _transparencyBlendMode = TRANSPARENT_MODE.None;
  242. }
  243. UpdateMaterialProperties ();
  244. isDirty = true;
  245. }
  246. }
  247. }
  248. [SerializeField]
  249. float
  250. _transparencyCutOff = 0.1f;
  251. public float transparencyCutOff {
  252. get { return _transparencyCutOff; }
  253. set {
  254. if (value != _transparencyCutOff) {
  255. _transparencyCutOff = value;
  256. UpdateMaterialProperties ();
  257. isDirty = true;
  258. }
  259. }
  260. }
  261. [SerializeField]
  262. bool
  263. _renderBeforeTransparent;
  264. public bool renderBeforeTransparent {
  265. get { return _renderBeforeTransparent; }
  266. set {
  267. if (value != _renderBeforeTransparent) {
  268. _renderBeforeTransparent = value;
  269. if (_renderBeforeTransparent) {
  270. _transparencyBlendMode = TRANSPARENT_MODE.None;
  271. }
  272. UpdateMaterialProperties ();
  273. UpdateRenderComponents ();
  274. isDirty = true;
  275. }
  276. }
  277. }
  278. [SerializeField]
  279. GameObject
  280. _sun;
  281. public GameObject sun {
  282. get { return _sun; }
  283. set {
  284. if (value != _sun) {
  285. _sun = value;
  286. UpdateSun ();
  287. }
  288. }
  289. }
  290. [SerializeField]
  291. bool
  292. _sunCopyColor = true;
  293. public bool sunCopyColor {
  294. get { return _sunCopyColor; }
  295. set {
  296. if (value != _sunCopyColor) {
  297. _sunCopyColor = value;
  298. UpdateMaterialProperties ();
  299. isDirty = true;
  300. }
  301. }
  302. }
  303. #endregion
  304. #region Fog Geometry settings
  305. [SerializeField]
  306. float
  307. _density = 1.0f;
  308. public float density {
  309. get { return _density; }
  310. set {
  311. if (value != _density) {
  312. _preset = FOG_PRESET.Custom;
  313. _density = value;
  314. UpdateMaterialProperties ();
  315. UpdateTextureAlpha ();
  316. UpdateTexture ();
  317. isDirty = true;
  318. }
  319. }
  320. }
  321. [SerializeField]
  322. float
  323. _noiseStrength = 0.8f;
  324. public float noiseStrength {
  325. get { return _noiseStrength; }
  326. set {
  327. if (value != _noiseStrength) {
  328. _preset = FOG_PRESET.Custom;
  329. _noiseStrength = value;
  330. UpdateMaterialProperties ();
  331. UpdateTextureAlpha ();
  332. UpdateTexture ();
  333. isDirty = true;
  334. }
  335. }
  336. }
  337. [SerializeField]
  338. float
  339. _noiseFinalMultiplier = 1f;
  340. public float noiseFinalMultiplier {
  341. get { return _noiseFinalMultiplier; }
  342. set {
  343. if (value != _noiseFinalMultiplier) {
  344. _preset = FOG_PRESET.Custom;
  345. _noiseFinalMultiplier = value;
  346. UpdateMaterialProperties ();
  347. UpdateTextureAlpha ();
  348. UpdateTexture ();
  349. isDirty = true;
  350. }
  351. }
  352. }
  353. [SerializeField]
  354. float
  355. _noiseSparse;
  356. public float noiseSparse {
  357. get { return _noiseSparse; }
  358. set {
  359. if (value != _noiseSparse) {
  360. _preset = FOG_PRESET.Custom;
  361. _noiseSparse = value;
  362. UpdateMaterialProperties ();
  363. UpdateTextureAlpha ();
  364. UpdateTexture ();
  365. isDirty = true;
  366. }
  367. }
  368. }
  369. [SerializeField]
  370. float
  371. _distance = 0f;
  372. public float distance {
  373. get { return _distance; }
  374. set {
  375. if (value != _distance) {
  376. _preset = FOG_PRESET.Custom;
  377. _distance = value;
  378. UpdateMaterialProperties ();
  379. isDirty = true;
  380. }
  381. }
  382. }
  383. [SerializeField]
  384. float
  385. _maxFogLength = 1000f;
  386. public float maxFogLength {
  387. get { return _maxFogLength; }
  388. set {
  389. if (value != _maxFogLength) {
  390. _maxFogLength = value;
  391. UpdateMaterialProperties ();
  392. isDirty = true;
  393. }
  394. }
  395. }
  396. [SerializeField]
  397. float
  398. _maxFogLengthFallOff = 0f;
  399. public float maxFogLengthFallOff {
  400. get { return _maxFogLengthFallOff; }
  401. set {
  402. if (value != _maxFogLengthFallOff) {
  403. _maxFogLengthFallOff = value;
  404. UpdateMaterialProperties ();
  405. isDirty = true;
  406. }
  407. }
  408. }
  409. [SerializeField]
  410. float
  411. _distanceFallOff = 0f;
  412. public float distanceFallOff {
  413. get { return _distanceFallOff; }
  414. set {
  415. if (value != _distanceFallOff) {
  416. _preset = FOG_PRESET.Custom;
  417. _distanceFallOff = value;
  418. UpdateMaterialProperties ();
  419. isDirty = true;
  420. }
  421. }
  422. }
  423. [SerializeField]
  424. float
  425. _height = 4.0f;
  426. public float height {
  427. get { return _height; }
  428. set {
  429. if (value != _height) {
  430. _preset = FOG_PRESET.Custom;
  431. _height = Mathf.Max (value, 0.00001f);
  432. UpdateMaterialProperties ();
  433. isDirty = true;
  434. }
  435. }
  436. }
  437. [SerializeField]
  438. float
  439. _baselineHeight = 0f;
  440. public float baselineHeight {
  441. get { return _baselineHeight; }
  442. set {
  443. if (value != _baselineHeight) {
  444. _preset = FOG_PRESET.Custom;
  445. _baselineHeight = value;
  446. if (_fogAreaRadius > 0)
  447. _fogAreaPosition.y = _baselineHeight;
  448. UpdateMaterialProperties ();
  449. isDirty = true;
  450. }
  451. }
  452. }
  453. [SerializeField]
  454. bool
  455. _baselineRelativeToCamera = false;
  456. public bool baselineRelativeToCamera {
  457. get { return _baselineRelativeToCamera; }
  458. set {
  459. if (value != _baselineRelativeToCamera) {
  460. _preset = FOG_PRESET.Custom;
  461. _baselineRelativeToCamera = value;
  462. UpdateMaterialProperties ();
  463. isDirty = true;
  464. }
  465. }
  466. }
  467. [SerializeField]
  468. float
  469. _baselineRelativeToCameraDelay = 0;
  470. public float baselineRelativeToCameraDelay {
  471. get { return _baselineRelativeToCameraDelay; }
  472. set {
  473. if (value != _baselineRelativeToCameraDelay) {
  474. _baselineRelativeToCameraDelay = value;
  475. UpdateMaterialProperties ();
  476. isDirty = true;
  477. }
  478. }
  479. }
  480. [SerializeField]
  481. float
  482. _noiseScale = 1;
  483. public float noiseScale {
  484. get { return _noiseScale; }
  485. set {
  486. if (value != _noiseScale) {
  487. _preset = FOG_PRESET.Custom;
  488. _noiseScale = value;
  489. UpdateMaterialProperties ();
  490. isDirty = true;
  491. }
  492. }
  493. }
  494. #endregion
  495. #region Fog Style settings
  496. [SerializeField]
  497. float
  498. _alpha = 1.0f;
  499. public float alpha {
  500. get { return _alpha; }
  501. set {
  502. if (value != _alpha) {
  503. _preset = FOG_PRESET.Custom;
  504. _alpha = value;
  505. currentFogAlpha = _alpha;
  506. UpdateMaterialProperties ();
  507. isDirty = true;
  508. }
  509. }
  510. }
  511. [SerializeField]
  512. Color
  513. _color = new Color (0.89f, 0.89f, 0.89f, 1);
  514. public Color color {
  515. get { return _color; }
  516. set {
  517. if (value != _color) {
  518. _preset = FOG_PRESET.Custom;
  519. _color = value;
  520. currentFogColor = _color;
  521. UpdateMaterialProperties ();
  522. isDirty = true;
  523. }
  524. }
  525. }
  526. [SerializeField]
  527. Color
  528. _specularColor = new Color (1, 1, 0.8f, 1);
  529. public Color specularColor {
  530. get { return _specularColor; }
  531. set {
  532. if (value != _specularColor) {
  533. _preset = FOG_PRESET.Custom;
  534. _specularColor = value;
  535. currentFogSpecularColor = _specularColor;
  536. UpdateMaterialProperties ();
  537. UpdateTexture ();
  538. isDirty = true;
  539. }
  540. }
  541. }
  542. [SerializeField]
  543. float
  544. _specularThreshold = 0.6f;
  545. public float specularThreshold {
  546. get { return _specularThreshold; }
  547. set {
  548. if (value != _specularThreshold) {
  549. _preset = FOG_PRESET.Custom;
  550. _specularThreshold = value;
  551. UpdateTexture ();
  552. isDirty = true;
  553. }
  554. }
  555. }
  556. [SerializeField]
  557. float
  558. _specularIntensity = 0.2f;
  559. public float specularIntensity {
  560. get { return _specularIntensity; }
  561. set {
  562. if (value != _specularIntensity) {
  563. _preset = FOG_PRESET.Custom;
  564. _specularIntensity = value;
  565. UpdateMaterialProperties ();
  566. UpdateTexture ();
  567. isDirty = true;
  568. }
  569. }
  570. }
  571. [SerializeField]
  572. Vector3
  573. _lightDirection = new Vector3 (1, 0, -1);
  574. public Vector3 lightDirection {
  575. get { return _lightDirection; }
  576. set {
  577. if (value != _lightDirection) {
  578. _preset = FOG_PRESET.Custom;
  579. _lightDirection = value;
  580. UpdateMaterialProperties ();
  581. UpdateTexture ();
  582. isDirty = true;
  583. }
  584. }
  585. }
  586. [SerializeField]
  587. float
  588. _lightIntensity = 0.2f;
  589. public float lightIntensity {
  590. get { return _lightIntensity; }
  591. set {
  592. if (value != _lightIntensity) {
  593. _preset = FOG_PRESET.Custom;
  594. _lightIntensity = value;
  595. UpdateMaterialProperties ();
  596. UpdateTexture ();
  597. isDirty = true;
  598. }
  599. }
  600. }
  601. [SerializeField]
  602. Color
  603. _lightColor = Color.white;
  604. public Color lightColor {
  605. get { return _lightColor; }
  606. set {
  607. if (value != _lightColor) {
  608. _preset = FOG_PRESET.Custom;
  609. _lightColor = value;
  610. currentLightColor = _lightColor;
  611. UpdateMaterialProperties ();
  612. UpdateTexture ();
  613. isDirty = true;
  614. }
  615. }
  616. }
  617. [SerializeField]
  618. int
  619. _updateTextureSpread = 1;
  620. public int updateTextureSpread {
  621. get { return _updateTextureSpread; }
  622. set {
  623. if (value != _updateTextureSpread) {
  624. _updateTextureSpread = value;
  625. isDirty = true;
  626. }
  627. }
  628. }
  629. [SerializeField]
  630. float
  631. _speed = 0.01f;
  632. public float speed {
  633. get { return _speed; }
  634. set {
  635. if (value != _speed) {
  636. _preset = FOG_PRESET.Custom;
  637. _speed = value;
  638. if (!Application.isPlaying)
  639. UpdateWindSpeedQuick ();
  640. isDirty = true;
  641. }
  642. }
  643. }
  644. [SerializeField]
  645. Vector3
  646. _windDirection = new Vector3 (-1, 0, 0);
  647. public Vector3 windDirection {
  648. get { return _windDirection; }
  649. set {
  650. if (value != _windDirection) {
  651. _preset = FOG_PRESET.Custom;
  652. _windDirection = value.normalized;
  653. if (!Application.isPlaying)
  654. UpdateWindSpeedQuick ();
  655. isDirty = true;
  656. }
  657. }
  658. }
  659. [SerializeField]
  660. bool
  661. _useRealTime = false;
  662. public bool useRealTime {
  663. get { return _useRealTime; }
  664. set {
  665. if (value != _useRealTime) {
  666. _useRealTime = value;
  667. isDirty = true;
  668. }
  669. }
  670. }
  671. #endregion
  672. #region Sky Haze settings
  673. [SerializeField]
  674. Color
  675. _skyColor = new Color (0.89f, 0.89f, 0.89f, 1);
  676. public Color skyColor {
  677. get { return _skyColor; }
  678. set {
  679. if (value != _skyColor) {
  680. _preset = FOG_PRESET.Custom;
  681. _skyColor = value;
  682. UpdateMaterialProperties ();
  683. isDirty = true;
  684. }
  685. }
  686. }
  687. [SerializeField]
  688. float
  689. _skyHaze = 50.0f;
  690. public float skyHaze {
  691. get { return _skyHaze; }
  692. set {
  693. if (value != _skyHaze) {
  694. _preset = FOG_PRESET.Custom;
  695. _skyHaze = value;
  696. if (!Application.isPlaying)
  697. UpdateWindSpeedQuick ();
  698. isDirty = true;
  699. }
  700. }
  701. }
  702. [SerializeField]
  703. float
  704. _skySpeed = 0.3f;
  705. public float skySpeed {
  706. get { return _skySpeed; }
  707. set {
  708. if (value != _skySpeed) {
  709. _preset = FOG_PRESET.Custom;
  710. _skySpeed = value;
  711. isDirty = true;
  712. }
  713. }
  714. }
  715. [SerializeField]
  716. float
  717. _skyNoiseStrength = 0.1f;
  718. public float skyNoiseStrength {
  719. get { return _skyNoiseStrength; }
  720. set {
  721. if (value != _skyNoiseStrength) {
  722. _preset = FOG_PRESET.Custom;
  723. _skyNoiseStrength = value;
  724. if (!Application.isPlaying)
  725. UpdateWindSpeedQuick ();
  726. isDirty = true;
  727. }
  728. }
  729. }
  730. [SerializeField]
  731. float
  732. _skyAlpha = 1.0f;
  733. public float skyAlpha {
  734. get { return _skyAlpha; }
  735. set {
  736. if (value != _skyAlpha) {
  737. _preset = FOG_PRESET.Custom;
  738. _skyAlpha = value;
  739. UpdateMaterialProperties ();
  740. isDirty = true;
  741. }
  742. }
  743. }
  744. [SerializeField]
  745. float
  746. _skyDepth = 0.999f;
  747. public float skyDepth {
  748. get { return _skyDepth; }
  749. set {
  750. if (value != _skyDepth) {
  751. _skyDepth = value;
  752. if (!Application.isPlaying)
  753. UpdateWindSpeedQuick ();
  754. isDirty = true;
  755. }
  756. }
  757. }
  758. #endregion
  759. #region Fog Void settings
  760. [SerializeField]
  761. GameObject
  762. _character;
  763. public GameObject character {
  764. get { return _character; }
  765. set {
  766. if (value != _character) {
  767. _character = value;
  768. isDirty = true;
  769. }
  770. }
  771. }
  772. [SerializeField]
  773. FOG_VOID_TOPOLOGY
  774. _fogVoidTopology = FOG_VOID_TOPOLOGY.Sphere;
  775. public FOG_VOID_TOPOLOGY fogVoidTopology {
  776. get { return _fogVoidTopology; }
  777. set {
  778. if (value != _fogVoidTopology) {
  779. _fogVoidTopology = value;
  780. UpdateMaterialProperties ();
  781. isDirty = true;
  782. }
  783. }
  784. }
  785. [SerializeField]
  786. float
  787. _fogVoidFallOff = 1.0f;
  788. public float fogVoidFallOff {
  789. get { return _fogVoidFallOff; }
  790. set {
  791. if (value != _fogVoidFallOff) {
  792. _preset = FOG_PRESET.Custom;
  793. _fogVoidFallOff = value;
  794. UpdateMaterialProperties ();
  795. isDirty = true;
  796. }
  797. }
  798. }
  799. [SerializeField]
  800. float
  801. _fogVoidRadius = 0.0f;
  802. public float fogVoidRadius {
  803. get { return _fogVoidRadius; }
  804. set {
  805. if (value != _fogVoidRadius) {
  806. _preset = FOG_PRESET.Custom;
  807. _fogVoidRadius = value;
  808. UpdateMaterialProperties ();
  809. isDirty = true;
  810. }
  811. }
  812. }
  813. [SerializeField]
  814. Vector3
  815. _fogVoidPosition = Vector3.zero;
  816. public Vector3 fogVoidPosition {
  817. get { return _fogVoidPosition; }
  818. set {
  819. if (value != _fogVoidPosition) {
  820. _preset = FOG_PRESET.Custom;
  821. _fogVoidPosition = value;
  822. UpdateMaterialProperties ();
  823. isDirty = true;
  824. }
  825. }
  826. }
  827. [SerializeField]
  828. float
  829. _fogVoidDepth = 0.0f;
  830. public float fogVoidDepth {
  831. get { return _fogVoidDepth; }
  832. set {
  833. if (value != _fogVoidDepth) {
  834. _preset = FOG_PRESET.Custom;
  835. _fogVoidDepth = value;
  836. UpdateMaterialProperties ();
  837. isDirty = true;
  838. }
  839. }
  840. }
  841. [SerializeField]
  842. float
  843. _fogVoidHeight = 0.0f;
  844. public float fogVoidHeight {
  845. get { return _fogVoidHeight; }
  846. set {
  847. if (value != _fogVoidHeight) {
  848. _preset = FOG_PRESET.Custom;
  849. _fogVoidHeight = value;
  850. UpdateMaterialProperties ();
  851. isDirty = true;
  852. }
  853. }
  854. }
  855. [SerializeField]
  856. bool
  857. _fogVoidInverted = false;
  858. [Obsolete ("Fog Void inverted is now deprecated. Use Fog Area settings.")]
  859. public bool fogVoidInverted {
  860. get { return _fogVoidInverted; }
  861. set {
  862. _fogVoidInverted = value;
  863. }
  864. }
  865. #endregion
  866. #region Fog Area settings
  867. [SerializeField]
  868. bool
  869. _fogAreaShowGizmos = true;
  870. public bool fogAreaShowGizmos {
  871. get { return _fogAreaShowGizmos; }
  872. set {
  873. if (value != _fogAreaShowGizmos) {
  874. _fogAreaShowGizmos = value;
  875. UpdateMaterialProperties ();
  876. isDirty = true;
  877. }
  878. }
  879. }
  880. [SerializeField]
  881. GameObject
  882. _fogAreaCenter;
  883. public GameObject fogAreaCenter {
  884. get { return _fogAreaCenter; }
  885. set {
  886. if (value != _character) {
  887. _fogAreaCenter = value;
  888. isDirty = true;
  889. }
  890. }
  891. }
  892. [SerializeField]
  893. float
  894. _fogAreaFallOff = 1.0f;
  895. public float fogAreaFallOff {
  896. get { return _fogAreaFallOff; }
  897. set {
  898. if (value != _fogAreaFallOff) {
  899. _fogAreaFallOff = value;
  900. UpdateMaterialProperties ();
  901. isDirty = true;
  902. }
  903. }
  904. }
  905. [SerializeField]
  906. FOG_AREA_FOLLOW_MODE
  907. _fogAreaFollowMode = FOG_AREA_FOLLOW_MODE.FullXYZ;
  908. public FOG_AREA_FOLLOW_MODE fogAreaFollowMode {
  909. get { return _fogAreaFollowMode; }
  910. set {
  911. if (value != _fogAreaFollowMode) {
  912. _fogAreaFollowMode = value;
  913. UpdateMaterialProperties ();
  914. isDirty = true;
  915. }
  916. }
  917. }
  918. [SerializeField]
  919. FOG_AREA_TOPOLOGY
  920. _fogAreaTopology = FOG_AREA_TOPOLOGY.Sphere;
  921. public FOG_AREA_TOPOLOGY fogAreaTopology {
  922. get { return _fogAreaTopology; }
  923. set {
  924. if (value != _fogAreaTopology) {
  925. _fogAreaTopology = value;
  926. UpdateMaterialProperties ();
  927. isDirty = true;
  928. }
  929. }
  930. }
  931. [SerializeField]
  932. float
  933. _fogAreaRadius = 0.0f;
  934. public float fogAreaRadius {
  935. get { return _fogAreaRadius; }
  936. set {
  937. if (value != _fogAreaRadius) {
  938. _fogAreaRadius = value;
  939. UpdateMaterialProperties ();
  940. isDirty = true;
  941. }
  942. }
  943. }
  944. [SerializeField]
  945. Vector3
  946. _fogAreaPosition = Vector3.zero;
  947. public Vector3 fogAreaPosition {
  948. get { return _fogAreaPosition; }
  949. set {
  950. if (value != _fogAreaPosition) {
  951. _fogAreaPosition = value;
  952. if (_fogAreaCenter == null || _fogAreaFollowMode == FOG_AREA_FOLLOW_MODE.RestrictToXZPlane) {
  953. _baselineHeight = _fogAreaPosition.y;
  954. }
  955. UpdateMaterialProperties ();
  956. isDirty = true;
  957. }
  958. }
  959. }
  960. [SerializeField]
  961. float
  962. _fogAreaDepth = 0.0f;
  963. public float fogAreaDepth {
  964. get { return _fogAreaDepth; }
  965. set {
  966. if (value != _fogAreaDepth) {
  967. _fogAreaDepth = value;
  968. UpdateMaterialProperties ();
  969. isDirty = true;
  970. }
  971. }
  972. }
  973. [SerializeField]
  974. float
  975. _fogAreaHeight = 0.0f;
  976. public float fogAreaHeight {
  977. get { return _fogAreaHeight; }
  978. set {
  979. if (value != _fogAreaHeight) {
  980. _fogAreaHeight = value;
  981. UpdateMaterialProperties ();
  982. isDirty = true;
  983. }
  984. }
  985. }
  986. [SerializeField]
  987. FOG_AREA_SORTING_MODE
  988. _fogAreaSortingMode = FOG_AREA_SORTING_MODE.DistanceToCamera;
  989. public FOG_AREA_SORTING_MODE fogAreaSortingMode {
  990. get { return _fogAreaSortingMode; }
  991. set {
  992. if (value != _fogAreaSortingMode) {
  993. _fogAreaSortingMode = value;
  994. lastTimeSortInstances = 0;
  995. isDirty = true;
  996. }
  997. }
  998. }
  999. [SerializeField]
  1000. int
  1001. _fogAreaRenderOrder = 1;
  1002. public int fogAreaRenderOrder {
  1003. get { return _fogAreaRenderOrder; }
  1004. set {
  1005. if (value != _fogAreaRenderOrder) {
  1006. _fogAreaRenderOrder = value;
  1007. lastTimeSortInstances = 0;
  1008. isDirty = true;
  1009. }
  1010. }
  1011. }
  1012. #endregion
  1013. #region Point Light settings
  1014. public const int MAX_POINT_LIGHTS = 6;
  1015. [SerializeField]
  1016. GameObject[]
  1017. _pointLights = new GameObject[MAX_POINT_LIGHTS];
  1018. [SerializeField]
  1019. float[]
  1020. _pointLightRanges = new float[MAX_POINT_LIGHTS];
  1021. [SerializeField]
  1022. float[]
  1023. _pointLightIntensities = new float[MAX_POINT_LIGHTS] {
  1024. 1.0f,
  1025. 1.0f,
  1026. 1.0f,
  1027. 1.0f,
  1028. 1.0f,
  1029. 1.0f
  1030. };
  1031. [SerializeField]
  1032. float[]
  1033. _pointLightIntensitiesMultiplier = new float[MAX_POINT_LIGHTS] {
  1034. 1.0f,
  1035. 1.0f,
  1036. 1.0f,
  1037. 1.0f,
  1038. 1.0f,
  1039. 1.0f
  1040. };
  1041. [SerializeField]
  1042. Vector3[]
  1043. _pointLightPositions = new Vector3[MAX_POINT_LIGHTS];
  1044. [SerializeField]
  1045. Color[]
  1046. _pointLightColors = new Color[MAX_POINT_LIGHTS] {
  1047. new Color (1, 1, 0, 1),
  1048. new Color (1, 1, 0, 1),
  1049. new Color (1, 1, 0, 1),
  1050. new Color (1, 1, 0, 1),
  1051. new Color (1, 1, 0, 1),
  1052. new Color (1, 1, 0, 1)
  1053. };
  1054. [SerializeField]
  1055. bool
  1056. _pointLightTrackingAuto = false;
  1057. public bool pointLightTrackAuto {
  1058. get { return _pointLightTrackingAuto; }
  1059. set {
  1060. if (value != _pointLightTrackingAuto) {
  1061. _pointLightTrackingAuto = value;
  1062. TrackPointLights ();
  1063. isDirty = true;
  1064. }
  1065. }
  1066. }
  1067. [SerializeField]
  1068. Transform
  1069. _pointLightTrackingPivot;
  1070. public Transform pointLightTrackingPivot {
  1071. get { return _pointLightTrackingPivot; }
  1072. set {
  1073. if (value != _pointLightTrackingPivot) {
  1074. _pointLightTrackingPivot = value;
  1075. TrackPointLights ();
  1076. isDirty = true;
  1077. }
  1078. }
  1079. }
  1080. [SerializeField]
  1081. int
  1082. _pointLightTrackingCount = 0;
  1083. public int pointLightTrackingCount {
  1084. get { return _pointLightTrackingCount; }
  1085. set {
  1086. if (value != _pointLightTrackingCount) {
  1087. _pointLightTrackingCount = Mathf.Clamp (value, 0, MAX_POINT_LIGHTS);
  1088. TrackPointLights ();
  1089. isDirty = true;
  1090. }
  1091. }
  1092. }
  1093. [SerializeField]
  1094. float
  1095. _pointLightTrackingCheckInterval = 1f;
  1096. public float pointLightTrackingCheckInterval {
  1097. get { return _pointLightTrackingCheckInterval; }
  1098. set {
  1099. if (value != _pointLightTrackingCheckInterval) {
  1100. _pointLightTrackingCheckInterval = value;
  1101. TrackPointLights ();
  1102. isDirty = true;
  1103. }
  1104. }
  1105. }
  1106. [SerializeField]
  1107. float
  1108. _pointLightInscattering = 1f;
  1109. public float pointLightInscattering {
  1110. get { return _pointLightInscattering; }
  1111. set {
  1112. if (value != _pointLightInscattering) {
  1113. _pointLightInscattering = value;
  1114. isDirty = true;
  1115. }
  1116. }
  1117. }
  1118. [SerializeField]
  1119. float
  1120. _pointLightIntensity = 1f;
  1121. public float pointLightIntensity {
  1122. get { return _pointLightIntensity; }
  1123. set {
  1124. if (value != _pointLightIntensity) {
  1125. _pointLightIntensity = value;
  1126. isDirty = true;
  1127. }
  1128. }
  1129. }
  1130. #endregion
  1131. #region Optimization settings
  1132. [SerializeField]
  1133. int
  1134. _downsampling = 1;
  1135. public int downsampling {
  1136. get { return _downsampling; }
  1137. set {
  1138. if (value != _downsampling) {
  1139. _preset = FOG_PRESET.Custom;
  1140. _downsampling = value;
  1141. isDirty = true;
  1142. }
  1143. }
  1144. }
  1145. [SerializeField]
  1146. bool
  1147. _edgeImprove = false;
  1148. public bool edgeImprove {
  1149. get { return _edgeImprove; }
  1150. set {
  1151. if (value != _edgeImprove) {
  1152. _preset = FOG_PRESET.Custom;
  1153. _edgeImprove = value;
  1154. UpdateMaterialProperties ();
  1155. isDirty = true;
  1156. }
  1157. }
  1158. }
  1159. [SerializeField]
  1160. float
  1161. _edgeThreshold = 0.0005f;
  1162. public float edgeThreshold {
  1163. get { return _edgeThreshold; }
  1164. set {
  1165. if (value != _edgeThreshold) {
  1166. _preset = FOG_PRESET.Custom;
  1167. _edgeThreshold = value;
  1168. UpdateMaterialProperties ();
  1169. isDirty = true;
  1170. }
  1171. }
  1172. }
  1173. [SerializeField]
  1174. float
  1175. _stepping = 12.0f;
  1176. public float stepping {
  1177. get { return _stepping; }
  1178. set {
  1179. if (value != _stepping) {
  1180. _preset = FOG_PRESET.Custom;
  1181. _stepping = value;
  1182. UpdateMaterialProperties ();
  1183. isDirty = true;
  1184. }
  1185. }
  1186. }
  1187. [SerializeField]
  1188. float
  1189. _steppingNear = 1f;
  1190. public float steppingNear {
  1191. get { return _steppingNear; }
  1192. set {
  1193. if (value != _steppingNear) {
  1194. _preset = FOG_PRESET.Custom;
  1195. _steppingNear = value;
  1196. UpdateMaterialProperties ();
  1197. isDirty = true;
  1198. }
  1199. }
  1200. }
  1201. [SerializeField]
  1202. bool
  1203. _dithering = false;
  1204. public bool dithering {
  1205. get { return _dithering; }
  1206. set {
  1207. if (value != _dithering) {
  1208. _dithering = value;
  1209. UpdateMaterialProperties ();
  1210. isDirty = true;
  1211. }
  1212. }
  1213. }
  1214. [SerializeField]
  1215. float
  1216. _ditherStrength = 0.75f;
  1217. public float ditherStrength {
  1218. get { return _ditherStrength; }
  1219. set {
  1220. if (value != _ditherStrength) {
  1221. _ditherStrength = value;
  1222. UpdateMaterialProperties ();
  1223. isDirty = true;
  1224. }
  1225. }
  1226. }
  1227. [SerializeField]
  1228. float
  1229. _jitterStrength = 0.5f;
  1230. public float jitterStrength {
  1231. get { return _jitterStrength; }
  1232. set {
  1233. if (value != _jitterStrength) {
  1234. _jitterStrength = value;
  1235. UpdateMaterialProperties ();
  1236. isDirty = true;
  1237. }
  1238. }
  1239. }
  1240. #endregion
  1241. #region Shafts settings
  1242. [SerializeField]
  1243. bool
  1244. _lightScatteringEnabled = false;
  1245. public bool lightScatteringEnabled {
  1246. get { return _lightScatteringEnabled; }
  1247. set {
  1248. if (value != _lightScatteringEnabled) {
  1249. _lightScatteringEnabled = value;
  1250. UpdateMaterialProperties ();
  1251. isDirty = true;
  1252. }
  1253. }
  1254. }
  1255. [SerializeField]
  1256. float
  1257. _lightScatteringDiffusion = 0.7f;
  1258. public float lightScatteringDiffusion {
  1259. get { return _lightScatteringDiffusion; }
  1260. set {
  1261. if (value != _lightScatteringDiffusion) {
  1262. _lightScatteringDiffusion = value;
  1263. UpdateMaterialProperties ();
  1264. isDirty = true;
  1265. }
  1266. }
  1267. }
  1268. [SerializeField]
  1269. float
  1270. _lightScatteringSpread = 0.686f;
  1271. public float lightScatteringSpread {
  1272. get { return _lightScatteringSpread; }
  1273. set {
  1274. if (value != _lightScatteringSpread) {
  1275. _lightScatteringSpread = value;
  1276. UpdateMaterialProperties ();
  1277. isDirty = true;
  1278. }
  1279. }
  1280. }
  1281. [SerializeField]
  1282. int
  1283. _lightScatteringSamples = 16;
  1284. public int lightScatteringSamples {
  1285. get { return _lightScatteringSamples; }
  1286. set {
  1287. if (value != _lightScatteringSamples) {
  1288. _lightScatteringSamples = value;
  1289. UpdateMaterialProperties ();
  1290. isDirty = true;
  1291. }
  1292. }
  1293. }
  1294. [SerializeField]
  1295. float
  1296. _lightScatteringWeight = 1.9f;
  1297. public float lightScatteringWeight {
  1298. get { return _lightScatteringWeight; }
  1299. set {
  1300. if (value != _lightScatteringWeight) {
  1301. _lightScatteringWeight = value;
  1302. UpdateMaterialProperties ();
  1303. isDirty = true;
  1304. }
  1305. }
  1306. }
  1307. [SerializeField]
  1308. float
  1309. _lightScatteringIllumination = 18f;
  1310. public float lightScatteringIllumination {
  1311. get { return _lightScatteringIllumination; }
  1312. set {
  1313. if (value != _lightScatteringIllumination) {
  1314. _lightScatteringIllumination = value;
  1315. UpdateMaterialProperties ();
  1316. isDirty = true;
  1317. }
  1318. }
  1319. }
  1320. [SerializeField]
  1321. float
  1322. _lightScatteringDecay = 0.986f;
  1323. public float lightScatteringDecay {
  1324. get { return _lightScatteringDecay; }
  1325. set {
  1326. if (value != _lightScatteringDecay) {
  1327. _lightScatteringDecay = value;
  1328. UpdateMaterialProperties ();
  1329. isDirty = true;
  1330. }
  1331. }
  1332. }
  1333. [SerializeField]
  1334. float
  1335. _lightScatteringExposure = 0;
  1336. //0.02f;
  1337. public float lightScatteringExposure {
  1338. get { return _lightScatteringExposure; }
  1339. set {
  1340. if (value != _lightScatteringExposure) {
  1341. _lightScatteringExposure = value;
  1342. UpdateMaterialProperties ();
  1343. isDirty = true;
  1344. }
  1345. }
  1346. }
  1347. [SerializeField]
  1348. float
  1349. _lightScatteringJittering = 0.5f;
  1350. public float lightScatteringJittering {
  1351. get { return _lightScatteringJittering; }
  1352. set {
  1353. if (value != _lightScatteringJittering) {
  1354. _lightScatteringJittering = value;
  1355. UpdateMaterialProperties ();
  1356. isDirty = true;
  1357. }
  1358. }
  1359. }
  1360. #endregion
  1361. #region Fog Blur
  1362. [SerializeField]
  1363. bool
  1364. _fogBlur = false;
  1365. public bool fogBlur {
  1366. get { return _fogBlur; }
  1367. set {
  1368. if (value != _fogBlur) {
  1369. _fogBlur = value;
  1370. UpdateMaterialProperties ();
  1371. isDirty = true;
  1372. }
  1373. }
  1374. }
  1375. [SerializeField]
  1376. float
  1377. _fogBlurDepth = 0.05f;
  1378. public float fogBlurDepth {
  1379. get { return _fogBlurDepth; }
  1380. set {
  1381. if (value != _fogBlurDepth) {
  1382. _fogBlurDepth = value;
  1383. UpdateMaterialProperties ();
  1384. isDirty = true;
  1385. }
  1386. }
  1387. }
  1388. #endregion
  1389. #region Sun Shadows
  1390. [SerializeField]
  1391. bool
  1392. _sunShadows = false;
  1393. public bool sunShadows {
  1394. get { return _sunShadows; }
  1395. set {
  1396. if (value != _sunShadows) {
  1397. _sunShadows = value;
  1398. CleanUpTextureDepthSun ();
  1399. if (_sunShadows) {
  1400. needUpdateDepthSunTexture = true;
  1401. } else {
  1402. DestroySunShadowsDependencies ();
  1403. }
  1404. UpdateMaterialProperties ();
  1405. isDirty = true;
  1406. }
  1407. }
  1408. }
  1409. [SerializeField]
  1410. LayerMask
  1411. _sunShadowsLayerMask = -1;
  1412. public LayerMask sunShadowsLayerMask {
  1413. get { return _sunShadowsLayerMask; }
  1414. set {
  1415. if (_sunShadowsLayerMask != value) {
  1416. _sunShadowsLayerMask = value;
  1417. isDirty = true;
  1418. }
  1419. }
  1420. }
  1421. [SerializeField]
  1422. float
  1423. _sunShadowsStrength = 0.5f;
  1424. public float sunShadowsStrength {
  1425. get { return _sunShadowsStrength; }
  1426. set {
  1427. if (value != _sunShadowsStrength) {
  1428. _sunShadowsStrength = value;
  1429. UpdateMaterialProperties ();
  1430. isDirty = true;
  1431. }
  1432. }
  1433. }
  1434. [SerializeField]
  1435. float
  1436. _sunShadowsBias = 0.1f;
  1437. public float sunShadowsBias {
  1438. get { return _sunShadowsBias; }
  1439. set {
  1440. if (value != _sunShadowsBias) {
  1441. _sunShadowsBias = value;
  1442. needUpdateDepthSunTexture = true;
  1443. UpdateMaterialProperties ();
  1444. isDirty = true;
  1445. }
  1446. }
  1447. }
  1448. [SerializeField]
  1449. float
  1450. _sunShadowsJitterStrength = 0.1f;
  1451. public float sunShadowsJitterStrength {
  1452. get { return _sunShadowsJitterStrength; }
  1453. set {
  1454. if (value != _sunShadowsJitterStrength) {
  1455. _sunShadowsJitterStrength = value;
  1456. UpdateMaterialProperties ();
  1457. isDirty = true;
  1458. }
  1459. }
  1460. }
  1461. [SerializeField]
  1462. int
  1463. _sunShadowsResolution = 2;
  1464. // default = 2^(9+2) = 2048 texture size
  1465. public int sunShadowsResolution {
  1466. get { return _sunShadowsResolution; }
  1467. set {
  1468. if (value != _sunShadowsResolution) {
  1469. _sunShadowsResolution = value;
  1470. needUpdateDepthSunTexture = true;
  1471. CleanUpTextureDepthSun ();
  1472. UpdateMaterialProperties ();
  1473. isDirty = true;
  1474. }
  1475. }
  1476. }
  1477. [SerializeField]
  1478. float
  1479. _sunShadowsMaxDistance = 200f;
  1480. public float sunShadowsMaxDistance {
  1481. get { return _sunShadowsMaxDistance; }
  1482. set {
  1483. if (value != _sunShadowsMaxDistance) {
  1484. _sunShadowsMaxDistance = value;
  1485. needUpdateDepthSunTexture = true;
  1486. UpdateMaterialProperties ();
  1487. isDirty = true;
  1488. }
  1489. }
  1490. }
  1491. [SerializeField]
  1492. SUN_SHADOWS_BAKE_MODE
  1493. _sunShadowsBakeMode = SUN_SHADOWS_BAKE_MODE.Discrete;
  1494. public SUN_SHADOWS_BAKE_MODE sunShadowsBakeMode {
  1495. get { return _sunShadowsBakeMode; }
  1496. set {
  1497. if (value != _sunShadowsBakeMode) {
  1498. _sunShadowsBakeMode = value;
  1499. needUpdateDepthSunTexture = true;
  1500. UpdateMaterialProperties ();
  1501. isDirty = true;
  1502. }
  1503. }
  1504. }
  1505. [SerializeField]
  1506. float
  1507. _sunShadowsRefreshInterval = 0;
  1508. // 0 = no update unless Sun changes position
  1509. public float sunShadowsRefreshInterval {
  1510. get { return _sunShadowsRefreshInterval; }
  1511. set {
  1512. if (value != _sunShadowsRefreshInterval) {
  1513. _sunShadowsRefreshInterval = value;
  1514. UpdateMaterialProperties ();
  1515. isDirty = true;
  1516. }
  1517. }
  1518. }
  1519. [SerializeField]
  1520. float
  1521. _sunShadowsCancellation = 0f;
  1522. public float sunShadowsCancellation {
  1523. get { return _sunShadowsCancellation; }
  1524. set {
  1525. if (value != _sunShadowsCancellation) {
  1526. _sunShadowsCancellation = value;
  1527. UpdateMaterialProperties ();
  1528. isDirty = true;
  1529. }
  1530. }
  1531. }
  1532. #endregion
  1533. #region Turbulence
  1534. [SerializeField]
  1535. float
  1536. _turbulenceStrength = 0f;
  1537. public float turbulenceStrength {
  1538. get { return _turbulenceStrength; }
  1539. set {
  1540. if (value != _turbulenceStrength) {
  1541. _turbulenceStrength = value;
  1542. if (_turbulenceStrength <= 0f)
  1543. UpdateTexture (); // reset texture to normal
  1544. UpdateMaterialProperties ();
  1545. isDirty = true;
  1546. }
  1547. }
  1548. }
  1549. #endregion
  1550. #region Other settings
  1551. [SerializeField]
  1552. bool
  1553. _useXYPlane = false;
  1554. public bool useXYPlane {
  1555. get { return _useXYPlane; }
  1556. set {
  1557. if (value != _useXYPlane) {
  1558. _useXYPlane = value;
  1559. if (_sunShadows)
  1560. needUpdateDepthSunTexture = true;
  1561. UpdateMaterialProperties ();
  1562. isDirty = true;
  1563. }
  1564. }
  1565. }
  1566. [SerializeField]
  1567. bool
  1568. _useSinglePassStereoRenderingMatrix = false;
  1569. public bool useSinglePassStereoRenderingMatrix {
  1570. get { return _useSinglePassStereoRenderingMatrix; }
  1571. set {
  1572. if (value != _useSinglePassStereoRenderingMatrix) {
  1573. _useSinglePassStereoRenderingMatrix = value;
  1574. isDirty = true;
  1575. }
  1576. }
  1577. }
  1578. [SerializeField]
  1579. SPSR_BEHAVIOUR _spsrBehaviour = SPSR_BEHAVIOUR.AutoDetectInEditor;
  1580. public SPSR_BEHAVIOUR spsrBehaviour {
  1581. get { return _spsrBehaviour; }
  1582. set {
  1583. if (value != _spsrBehaviour) {
  1584. _spsrBehaviour = value;
  1585. isDirty = true;
  1586. }
  1587. }
  1588. }
  1589. #endregion
  1590. // State variables
  1591. public Camera fogCamera { get { return mainCamera; } }
  1592. public int renderingInstancesCount { get { return _renderingInstancesCount; } }
  1593. public bool hasCamera { get { return _hasCamera; } }
  1594. [NonSerialized]
  1595. public float distanceToCameraMin, distanceToCameraMax, distanceToCamera, distanceToCameraYAxis;
  1596. public VolumetricFog fogRenderer;
  1597. #region Internal variables
  1598. bool isPartOfScene;
  1599. // transitions
  1600. float initialFogAlpha, targetFogAlpha;
  1601. float initialSkyHazeAlpha, targetSkyHazeAlpha;
  1602. bool transitionAlpha, transitionColor, transitionSpecularColor, transitionLightColor, transitionProfile;
  1603. bool targetColorActive, targetSpecularColorActive, targetLightColorActive;
  1604. Color initialFogColor, targetFogColor;
  1605. Color initialFogSpecularColor, targetFogSpecularColor;
  1606. Color initialLightColor, targetLightColor;
  1607. float transitionDuration;
  1608. float transitionStartTime;
  1609. float currentFogAlpha, currentSkyHazeAlpha;
  1610. Color currentFogColor, currentFogSpecularColor, currentLightColor;
  1611. VolumetricFogProfile initialProfile, targetProfile;
  1612. // fog height related
  1613. float oldBaselineRelativeCameraY;
  1614. float currentFogAltitude;
  1615. // sky related
  1616. float skyHazeSpeedAcum;
  1617. // rendering
  1618. bool _hasCamera;
  1619. // if this script is attached to a camera or to another object
  1620. Camera mainCamera;
  1621. List<string> shaderKeywords;
  1622. Material blurMat;
  1623. RenderBuffer[] mrt;
  1624. int _renderingInstancesCount;
  1625. bool shouldUpdateMaterialProperties;
  1626. [NonSerialized]
  1627. public Material fogMat;
  1628. RenderTexture depthTexture, depthSunTexture, reducedDestination;
  1629. // point light related
  1630. Light[] pointLightComponents = new Light[MAX_POINT_LIGHTS];
  1631. Light[] lastFoundLights, lightBuffer;
  1632. GameObject[] currentLights = new GameObject[MAX_POINT_LIGHTS];
  1633. float trackPointAutoLastTime;
  1634. float trackPointCheckNewLightsLastTime;
  1635. // transparency support related
  1636. Shader depthShader, depthShaderAndTrans;
  1637. GameObject depthCamObj;
  1638. Camera depthCam;
  1639. // fog texture/lighting/colors related
  1640. float lastTextureUpdate;
  1641. Vector3 windSpeedAcum;
  1642. Texture2D adjustedTexture;
  1643. Color[] noiseColors, adjustedColors;
  1644. float sunLightIntensity = 1.0f;
  1645. bool needUpdateTexture, hasChangeAdjustedColorsAlpha;
  1646. int updatingTextureSlice;
  1647. Color updatingTextureLightColor;
  1648. Color lastRenderSettingsAmbientLight;
  1649. float lastRenderSettingsAmbientIntensity;
  1650. // Sun related
  1651. Light sunLight;
  1652. Vector2 oldSunPos;
  1653. float sunFade = 1f;
  1654. // Sun shadows related
  1655. GameObject depthSunCamObj;
  1656. Camera depthSunCam;
  1657. Shader depthSunShader;
  1658. bool needUpdateDepthSunTexture;
  1659. float lastShadowUpdateFrame;
  1660. // turbulence related
  1661. Texture2D adjustedChaosTexture;
  1662. Material chaosLerpMat;
  1663. float turbAcum;
  1664. float deltaTime, timeOfLastRender;
  1665. // fog instances stuff
  1666. List<VolumetricFog> fogInstances = new List<VolumetricFog> ();
  1667. List<VolumetricFog> fogRenderInstances = new List<VolumetricFog> ();
  1668. MeshRenderer mr;
  1669. float lastTimeSortInstances;
  1670. const float FOG_INSTANCES_SORT_INTERVAL = 2f;
  1671. Vector3 lastCamPos;
  1672. #endregion
  1673. #region Game loop events
  1674. void OnEnable () {
  1675. // Note: OnEnable can be called several times when using fog areas
  1676. isPartOfScene = isPartOfScene || IsPartOfScene ();
  1677. if (!isPartOfScene)
  1678. return;
  1679. if (_fogVoidInverted) { // conversion to fog area from fog void from previous versions
  1680. _fogVoidInverted = false;
  1681. _fogAreaCenter = _character;
  1682. _fogAreaDepth = _fogVoidDepth;
  1683. _fogAreaFallOff = _fogVoidFallOff;
  1684. _fogAreaHeight = _fogVoidHeight;
  1685. _fogAreaPosition = _fogVoidPosition;
  1686. _fogAreaRadius = _fogVoidRadius;
  1687. _fogVoidRadius = 0;
  1688. _character = null;
  1689. }
  1690. // Setup fog rendering system
  1691. mainCamera = gameObject.GetComponent<Camera> ();
  1692. _hasCamera = mainCamera != null;
  1693. if (_hasCamera) {
  1694. fogRenderer = this;
  1695. if (mainCamera.depthTextureMode == DepthTextureMode.None) {
  1696. mainCamera.depthTextureMode = DepthTextureMode.Depth;
  1697. }
  1698. } else {
  1699. if (fogRenderer == null) {
  1700. mainCamera = Camera.main;
  1701. if (mainCamera == null)
  1702. return;
  1703. fogRenderer = mainCamera.GetComponent<VolumetricFog> ();
  1704. if (fogRenderer == null) {
  1705. fogRenderer = mainCamera.gameObject.AddComponent<VolumetricFog> ();
  1706. fogRenderer.density = 0;
  1707. }
  1708. } else {
  1709. mainCamera = fogRenderer.mainCamera;
  1710. if (mainCamera == null)
  1711. mainCamera = fogRenderer.GetComponent<Camera> ();
  1712. }
  1713. }
  1714. // Check proper array initialization
  1715. if (_pointLights.Length < MAX_POINT_LIGHTS)
  1716. _pointLights = new GameObject[MAX_POINT_LIGHTS];
  1717. if (_pointLightColors.Length < MAX_POINT_LIGHTS)
  1718. _pointLightColors = new Color[MAX_POINT_LIGHTS];
  1719. if (_pointLightIntensities.Length < MAX_POINT_LIGHTS)
  1720. _pointLightIntensities = new float[MAX_POINT_LIGHTS];
  1721. if (_pointLightIntensitiesMultiplier.Length < MAX_POINT_LIGHTS)
  1722. _pointLightIntensitiesMultiplier = new float[MAX_POINT_LIGHTS];
  1723. if (_pointLightPositions.Length < MAX_POINT_LIGHTS)
  1724. _pointLightPositions = new Vector3[MAX_POINT_LIGHTS];
  1725. if (_pointLightRanges.Length < MAX_POINT_LIGHTS)
  1726. _pointLightRanges = new float[MAX_POINT_LIGHTS];
  1727. if (_pointLightTrackingPivot == null) {
  1728. _pointLightTrackingPivot = transform;
  1729. }
  1730. // Initialize material
  1731. if (fogMat == null) {
  1732. InitFogMaterial ();
  1733. if (_profile != null) {
  1734. _profile.Load (this);
  1735. }
  1736. } else {
  1737. UpdateMaterialPropertiesNow ();
  1738. }
  1739. // Register on other Volumetric Fog & Mist renderer if needed
  1740. RegisterWithRenderer ();
  1741. #if UNITY_EDITOR
  1742. if (EditorPrefs.GetInt (VFM_BUILD_HINT) == 0) {
  1743. EditorPrefs.SetInt (VFM_BUILD_HINT, 1);
  1744. EditorUtility.DisplayDialog ("Volumetric Fog & Mist Update: User Action Required", "Please check the 'Build Options' section in Volumetric Fog inspector for shader capabilities and make sure you disable unused features to optimize build size and compilation time.\n\nOtherwise when you build the game it will take a long time or even get stuck during shader compilation.", "Ok");
  1745. }
  1746. #endif
  1747. }
  1748. void OnDestroy () {
  1749. // Unregister on other Volumetric Fog & Mist renderer if needed
  1750. if (!_hasCamera && fogRenderer != null) {
  1751. fogRenderer.UnregisterFogArea (this);
  1752. } else {
  1753. UnregisterFogArea (this);
  1754. }
  1755. if (depthCamObj != null) {
  1756. DestroyImmediate (depthCamObj);
  1757. depthCamObj = null;
  1758. }
  1759. if (adjustedTexture != null) {
  1760. DestroyImmediate (adjustedTexture);
  1761. adjustedTexture = null;
  1762. }
  1763. if (chaosLerpMat != null) {
  1764. DestroyImmediate (chaosLerpMat);
  1765. chaosLerpMat = null;
  1766. }
  1767. if (adjustedChaosTexture != null) {
  1768. DestroyImmediate (adjustedChaosTexture);
  1769. adjustedChaosTexture = null;
  1770. }
  1771. if (blurMat != null) {
  1772. DestroyImmediate (blurMat);
  1773. blurMat = null;
  1774. }
  1775. if (fogMat != null) {
  1776. DestroyImmediate (fogMat);
  1777. fogMat = null;
  1778. }
  1779. CleanUpDepthTexture ();
  1780. DestroySunShadowsDependencies ();
  1781. }
  1782. public void DestroySelf () {
  1783. DestroyRenderComponent<VolumetricFogPreT> ();
  1784. DestroyRenderComponent<VolumetricFogPosT> ();
  1785. DestroyImmediate (this);
  1786. }
  1787. void Start () {
  1788. currentFogAlpha = _alpha;
  1789. currentSkyHazeAlpha = _skyAlpha;
  1790. lastTextureUpdate = Time.time + TIME_BETWEEN_TEXTURE_UPDATES;
  1791. RegisterWithRenderer (); // ensures it's properly registered
  1792. Update ();
  1793. }
  1794. // Check possible alpha transition
  1795. void Update () {
  1796. if (!isPartOfScene)
  1797. return;
  1798. // Updates sun illumination
  1799. if (fogRenderer.sun != null) {
  1800. Vector3 lightDir = fogRenderer.sun.transform.forward;
  1801. // bool mayUpdateTexture = !Application.isPlaying || _sunShadowsBakeMode == SUN_SHADOWS_BAKE_MODE.Realtime || (updatingTextureSlice < 0 && Time.time - lastTextureUpdate >= TIME_BETWEEN_TEXTURE_UPDATES);
  1802. bool mayUpdateTexture = !Application.isPlaying || (updatingTextureSlice < 0 && Time.time - lastTextureUpdate >= TIME_BETWEEN_TEXTURE_UPDATES);
  1803. if (mayUpdateTexture) {
  1804. // if (_sunShadows && _sunShadowsBakeMode == SUN_SHADOWS_BAKE_MODE.Realtime)
  1805. // needUpdateTexture = true;
  1806. if (lightDir != _lightDirection) {
  1807. _lightDirection = lightDir;
  1808. needUpdateTexture = true;
  1809. needUpdateDepthSunTexture = true;
  1810. }
  1811. if (sunLight != null) {
  1812. if (_sunCopyColor && sunLight.color != _lightColor) {
  1813. _lightColor = sunLight.color;
  1814. needUpdateTexture = true;
  1815. }
  1816. if (sunLightIntensity != sunLight.intensity) {
  1817. sunLightIntensity = sunLight.intensity;
  1818. needUpdateTexture = true;
  1819. }
  1820. }
  1821. }
  1822. }
  1823. // Check changes in render settings that affect fog colors
  1824. if (!needUpdateTexture) {
  1825. if (_lightingModel == LIGHTING_MODEL.Classic) {
  1826. if (lastRenderSettingsAmbientIntensity != RenderSettings.ambientIntensity) {
  1827. needUpdateTexture = true;
  1828. } else if (lastRenderSettingsAmbientLight != RenderSettings.ambientLight) {
  1829. needUpdateTexture = true;
  1830. }
  1831. } else if (_lightingModel == LIGHTING_MODEL.Natural) {
  1832. if (lastRenderSettingsAmbientLight != RenderSettings.ambientLight) {
  1833. needUpdateTexture = true;
  1834. }
  1835. }
  1836. }
  1837. // Check profile transition
  1838. if (transitionProfile) {
  1839. float t = (Time.time - transitionStartTime) / transitionDuration;
  1840. if (t > 1)
  1841. t = 1;
  1842. VolumetricFogProfile.Lerp (initialProfile, targetProfile, t, this);
  1843. if (t >= 1f) {
  1844. transitionProfile = false;
  1845. }
  1846. }
  1847. // Check alpha transition
  1848. if (transitionAlpha) {
  1849. if (targetFogAlpha >= 0 || targetSkyHazeAlpha >= 0) {
  1850. if (targetFogAlpha != currentFogAlpha || targetSkyHazeAlpha != currentSkyHazeAlpha) {
  1851. if (transitionDuration > 0) {
  1852. currentFogAlpha = Mathf.Lerp (initialFogAlpha, targetFogAlpha, (Time.time - transitionStartTime) / transitionDuration);
  1853. currentSkyHazeAlpha = Mathf.Lerp (initialSkyHazeAlpha, targetSkyHazeAlpha, (Time.time - transitionStartTime) / transitionDuration);
  1854. } else {
  1855. currentFogAlpha = targetFogAlpha;
  1856. currentSkyHazeAlpha = targetSkyHazeAlpha;
  1857. transitionAlpha = false;
  1858. }
  1859. fogMat.SetFloat ("_FogAlpha", currentFogAlpha);
  1860. UpdateSkyColor (currentSkyHazeAlpha);
  1861. }
  1862. } else if (currentFogAlpha != _alpha || currentSkyHazeAlpha != _skyAlpha) {
  1863. if (transitionDuration > 0) {
  1864. currentFogAlpha = Mathf.Lerp (initialFogAlpha, _alpha, (Time.time - transitionStartTime) / transitionDuration);
  1865. currentSkyHazeAlpha = Mathf.Lerp (initialSkyHazeAlpha, alpha, (Time.time - transitionStartTime) / transitionDuration);
  1866. } else {
  1867. currentFogAlpha = _alpha;
  1868. currentSkyHazeAlpha = _skyAlpha;
  1869. transitionAlpha = false;
  1870. }
  1871. fogMat.SetFloat ("_FogAlpha", currentFogAlpha);
  1872. UpdateSkyColor (currentSkyHazeAlpha);
  1873. }
  1874. }
  1875. // Check color transition
  1876. if (transitionColor) {
  1877. if (targetColorActive) {
  1878. if (targetFogColor != currentFogColor) {
  1879. if (transitionDuration > 0) {
  1880. currentFogColor = Color.Lerp (initialFogColor, targetFogColor, (Time.time - transitionStartTime) / transitionDuration);
  1881. } else {
  1882. currentFogColor = targetFogColor;
  1883. transitionColor = false;
  1884. }
  1885. }
  1886. } else if (currentFogColor != _color) {
  1887. if (transitionDuration > 0) {
  1888. currentFogColor = Color.Lerp (initialFogColor, _color, (Time.time - transitionStartTime) / transitionDuration);
  1889. } else {
  1890. currentFogColor = _color;
  1891. transitionColor = false;
  1892. }
  1893. }
  1894. UpdateMaterialFogColor ();
  1895. }
  1896. // Check color specular transition
  1897. if (transitionSpecularColor) {
  1898. if (targetSpecularColorActive) {
  1899. if (targetFogSpecularColor != currentFogSpecularColor) {
  1900. if (transitionDuration > 0) {
  1901. currentFogSpecularColor = Color.Lerp (initialFogSpecularColor, targetFogSpecularColor, (Time.time - transitionStartTime) / transitionDuration);
  1902. } else {
  1903. currentFogSpecularColor = targetFogSpecularColor;
  1904. transitionSpecularColor = false;
  1905. }
  1906. needUpdateTexture = true;
  1907. }
  1908. } else if (currentFogSpecularColor != _specularColor) {
  1909. if (transitionDuration > 0) {
  1910. currentFogSpecularColor = Color.Lerp (initialFogSpecularColor, _specularColor, (Time.time - transitionStartTime) / transitionDuration);
  1911. } else {
  1912. currentFogSpecularColor = _specularColor;
  1913. transitionSpecularColor = false;
  1914. }
  1915. needUpdateTexture = true;
  1916. }
  1917. }
  1918. // Check color specular transition
  1919. if (transitionLightColor) {
  1920. if (targetLightColorActive) {
  1921. if (targetLightColor != currentLightColor) {
  1922. if (transitionDuration > 0) {
  1923. currentLightColor = Color.Lerp (initialLightColor, targetLightColor, (Time.time - transitionStartTime) / transitionDuration);
  1924. } else {
  1925. currentLightColor = targetLightColor;
  1926. transitionLightColor = false;
  1927. }
  1928. needUpdateTexture = true;
  1929. }
  1930. } else if (currentLightColor != _lightColor) {
  1931. if (transitionDuration > 0) {
  1932. currentLightColor = Color.Lerp (initialLightColor, _lightColor, (Time.time - transitionStartTime) / transitionDuration);
  1933. } else {
  1934. currentLightColor = _lightColor;
  1935. transitionLightColor = false;
  1936. }
  1937. needUpdateTexture = true;
  1938. }
  1939. }
  1940. if (_baselineRelativeToCamera) {
  1941. UpdateMaterialHeights ();
  1942. } else if (_character != null) {
  1943. _fogVoidPosition = _character.transform.position;
  1944. UpdateMaterialHeights ();
  1945. }
  1946. #if UNITY_EDITOR
  1947. CheckFogAreaDimensions(); // This is called in OnRenderImage BUT if Game View is not visible, fog area dimensions are not updated and gizmos won't appear with correct size, so we force dimensions check here just in case
  1948. #endif
  1949. if (_fogAreaCenter != null) {
  1950. if (_fogAreaFollowMode == FOG_AREA_FOLLOW_MODE.FullXYZ) {
  1951. _fogAreaPosition = _fogAreaCenter.transform.position;
  1952. } else {
  1953. _fogAreaPosition.x = _fogAreaCenter.transform.position.x;
  1954. _fogAreaPosition.z = _fogAreaCenter.transform.position.z;
  1955. }
  1956. UpdateMaterialHeights ();
  1957. }
  1958. if (_pointLightTrackingAuto) {
  1959. if (!Application.isPlaying || Time.time - trackPointAutoLastTime > _pointLightTrackingCheckInterval) {
  1960. trackPointAutoLastTime = Time.time;
  1961. TrackPointLights ();
  1962. }
  1963. }
  1964. if (updatingTextureSlice >= 0) {
  1965. UpdateTextureColors (adjustedColors, false);
  1966. } else if (needUpdateTexture) {
  1967. UpdateTexture ();
  1968. }
  1969. if (_hasCamera) {
  1970. // Restores fog of war
  1971. if (_fogOfWarEnabled)
  1972. FogOfWarUpdate ();
  1973. // Autoupdate of fog shadows
  1974. if (_sunShadows && fogRenderer.sun) {
  1975. CastSunShadows ();
  1976. }
  1977. // Sort fog instances
  1978. int fogInstancesCount = fogInstances.Count;
  1979. if (fogInstancesCount > 1) {
  1980. Vector3 camPos = mainCamera.transform.position;
  1981. bool needResort = !Application.isPlaying || Time.time - lastTimeSortInstances >= FOG_INSTANCES_SORT_INTERVAL;
  1982. if (!needResort) {
  1983. float camDist = (camPos.x - lastCamPos.x) * (camPos.x - lastCamPos.x) +
  1984. (camPos.y - lastCamPos.y) * (camPos.y - lastCamPos.y) +
  1985. (camPos.z - lastCamPos.z) * (camPos.z - lastCamPos.z);
  1986. if (camDist > 625) { // forces udpate every 25 meters
  1987. lastCamPos = camPos;
  1988. needResort = true;
  1989. }
  1990. }
  1991. if (needResort) {
  1992. lastTimeSortInstances = Time.time;
  1993. float camX = camPos.x;
  1994. float camY = camPos.y;
  1995. float camZ = camPos.z;
  1996. for (int k = 0; k < fogInstancesCount; k++) {
  1997. VolumetricFog fogInstance = fogInstances [k];
  1998. if (fogInstance != null) {
  1999. Vector3 pos = fogInstance.transform.position;
  2000. pos.y = fogInstance.currentFogAltitude;
  2001. float xdx = camX - pos.x;
  2002. float xdy = camY - pos.y;
  2003. float distYAxis = xdy * xdy;
  2004. float xdyh = camY - (pos.y + fogInstance.height);
  2005. float distYAxis2 = xdyh * xdyh;
  2006. fogInstance.distanceToCameraYAxis = distYAxis < distYAxis2 ? distYAxis : distYAxis2;
  2007. float xdz = camZ - pos.z;
  2008. float distSqr = xdx * xdx + xdy * xdy + xdz * xdz;
  2009. fogInstance.distanceToCamera = distSqr;
  2010. Vector3 min = pos - fogInstance.transform.localScale * 0.5f;
  2011. Vector3 max = pos + fogInstance.transform.localScale * 0.5f;
  2012. fogInstance.distanceToCameraMin = mainCamera.WorldToScreenPoint (min).z;
  2013. fogInstance.distanceToCameraMax = mainCamera.WorldToScreenPoint (max).z;
  2014. }
  2015. }
  2016. fogInstances.Sort ((VolumetricFog x, VolumetricFog y) => {
  2017. if (!x || !y) {
  2018. return 0;
  2019. }
  2020. if (x.fogAreaSortingMode == FOG_AREA_SORTING_MODE.Fixed || y.fogAreaSortingMode == FOG_AREA_SORTING_MODE.Fixed) {
  2021. if (x.fogAreaRenderOrder < y.fogAreaRenderOrder) {
  2022. return -1;
  2023. } else if (x.fogAreaRenderOrder > y.fogAreaRenderOrder) {
  2024. return 1;
  2025. } else {
  2026. return 0;
  2027. }
  2028. }
  2029. bool overlaps = (x.distanceToCameraMin < y.distanceToCameraMin && x.distanceToCameraMax > y.distanceToCameraMax) ||
  2030. (y.distanceToCameraMin < x.distanceToCameraMin && y.distanceToCameraMax > x.distanceToCameraMax);
  2031. if (overlaps || x.fogAreaSortingMode == FOG_AREA_SORTING_MODE.Altitude || y.fogAreaSortingMode == FOG_AREA_SORTING_MODE.Altitude) {
  2032. if (x.distanceToCameraYAxis < y.distanceToCameraYAxis) {
  2033. return 1;
  2034. } else if (x.distanceToCameraYAxis > y.distanceToCameraYAxis) {
  2035. return -1;
  2036. } else {
  2037. return 0;
  2038. }
  2039. }
  2040. if (x.distanceToCamera < y.distanceToCamera) {
  2041. return 1;
  2042. } else if (x.distanceToCamera > y.distanceToCamera) {
  2043. return -1;
  2044. } else {
  2045. return 0;
  2046. }
  2047. });
  2048. }
  2049. }
  2050. }
  2051. }
  2052. void OnPreCull () {
  2053. if (!enabled || !gameObject.activeSelf || fogMat == null || !_hasCamera || mainCamera == null)
  2054. return;
  2055. if (mainCamera.depthTextureMode == DepthTextureMode.None) {
  2056. mainCamera.depthTextureMode = DepthTextureMode.Depth;
  2057. }
  2058. if (_computeDepth) {
  2059. GetTransparentDepth ();
  2060. }
  2061. // Apply chaos
  2062. if (Application.isPlaying && _turbulenceStrength > 0f)
  2063. ApplyChaos ();
  2064. }
  2065. void OnDidApplyAnimationProperties () { // support for animating property based fields
  2066. shouldUpdateMaterialProperties = true;
  2067. }
  2068. #endregion
  2069. #region Setting up
  2070. bool IsPartOfScene () {
  2071. VolumetricFog[] fogs = FindObjectsOfType<VolumetricFog> ();
  2072. for (int k = 0; k < fogs.Length; k++) {
  2073. if (fogs [k] == this)
  2074. return true;
  2075. }
  2076. return false;
  2077. }
  2078. void InitFogMaterial () {
  2079. targetFogAlpha = -1;
  2080. targetSkyHazeAlpha = -1;
  2081. _skyColor.a = _skyAlpha;
  2082. updatingTextureSlice = -1;
  2083. fogMat = new Material (Shader.Find ("VolumetricFogAndMist/VolumetricFog"));
  2084. fogMat.hideFlags = HideFlags.DontSave;
  2085. Texture2D noiseTexture = Resources.Load<Texture2D> ("Textures/Noise3");
  2086. noiseColors = noiseTexture.GetPixels ();
  2087. adjustedColors = new Color[noiseColors.Length];
  2088. adjustedTexture = new Texture2D (noiseTexture.width, noiseTexture.height, TextureFormat.RGBA32, false);
  2089. adjustedTexture.hideFlags = HideFlags.DontSave;
  2090. timeOfLastRender = Time.time;
  2091. // Init & apply settings
  2092. UpdateTextureAlpha ();
  2093. UpdateSun ();
  2094. if (_pointLightTrackingAuto) {
  2095. TrackPointLights ();
  2096. } else {
  2097. UpdatePointLights ();
  2098. }
  2099. FogOfWarInit ();
  2100. if (fogOfWarTexture == null)
  2101. FogOfWarUpdateTexture ();
  2102. CopyTransitionValues ();
  2103. UpdatePreset ();
  2104. oldBaselineRelativeCameraY = mainCamera.transform.position.y;
  2105. if (_sunShadows)
  2106. needUpdateDepthSunTexture = true;
  2107. }
  2108. void UpdateRenderComponents () {
  2109. if (!_hasCamera)
  2110. return;
  2111. if (_renderBeforeTransparent) {
  2112. AssignRenderComponent<VolumetricFogPreT> ();
  2113. DestroyRenderComponent<VolumetricFogPosT> ();
  2114. } else if (_transparencyBlendMode == TRANSPARENT_MODE.Blend) {
  2115. AssignRenderComponent<VolumetricFogPreT> ();
  2116. AssignRenderComponent<VolumetricFogPosT> ();
  2117. } else {
  2118. AssignRenderComponent<VolumetricFogPosT> ();
  2119. DestroyRenderComponent<VolumetricFogPreT> ();
  2120. }
  2121. }
  2122. void DestroyRenderComponent<T> () where T : IVolumetricFogRenderComponent {
  2123. T[] cc = GetComponentsInChildren<T> (true);
  2124. for (int k = 0; k < cc.Length; k++) {
  2125. if (cc [k].fog == this || cc [k].fog == null) {
  2126. cc [k].DestroySelf ();
  2127. }
  2128. }
  2129. }
  2130. void AssignRenderComponent<T> () where T : UnityEngine.Component, IVolumetricFogRenderComponent {
  2131. T[] cc = GetComponentsInChildren<T> (true);
  2132. int freeCC = -1;
  2133. for (int k = 0; k < cc.Length; k++) {
  2134. if (cc [k].fog == this) {
  2135. return;
  2136. }
  2137. if (cc [k].fog == null)
  2138. freeCC = k;
  2139. }
  2140. if (freeCC < 0) {
  2141. gameObject.AddComponent<T> ().fog = this;
  2142. } else {
  2143. cc [freeCC].fog = this;
  2144. }
  2145. }
  2146. /// <summary>
  2147. /// Used internally to chain multiple fog areas into the main fog renderer.
  2148. /// </summary>
  2149. void RegisterFogArea (VolumetricFog fog) {
  2150. if (fogInstances.Contains (fog))
  2151. return;
  2152. fogInstances.Add (fog);
  2153. }
  2154. /// <summary>
  2155. /// Used internally to disconnect a non-enabled fog area from the main fog renderer.
  2156. /// </summary>
  2157. void UnregisterFogArea (VolumetricFog fog) {
  2158. if (!fogInstances.Contains (fog))
  2159. return;
  2160. fogInstances.Remove (fog);
  2161. }
  2162. void RegisterWithRenderer () {
  2163. if (!_hasCamera && fogRenderer != null) {
  2164. fogRenderer.RegisterFogArea (this);
  2165. } else {
  2166. RegisterFogArea (this);
  2167. }
  2168. lastTimeSortInstances = 0;
  2169. }
  2170. #endregion
  2171. #region Rendering stuff
  2172. internal void DoOnRenderImage (RenderTexture source, RenderTexture destination) {
  2173. // Check integrity of fog instances list
  2174. int registeredInstancesCount = fogInstances.Count;
  2175. fogRenderInstances.Clear ();
  2176. for (int k = 0; k < registeredInstancesCount; k++) {
  2177. if (fogInstances [k] != null && fogInstances [k].isActiveAndEnabled && fogInstances [k].density > 0)
  2178. fogRenderInstances.Add (fogInstances [k]);
  2179. }
  2180. _renderingInstancesCount = fogRenderInstances.Count;
  2181. if (_renderingInstancesCount == 0 || mainCamera == null) { // No available instances, cancel any rendering
  2182. Graphics.Blit (source, destination);
  2183. return;
  2184. }
  2185. if (_hasCamera && _density <= 0 && shouldUpdateMaterialProperties) {
  2186. // This fog renderer might require updating its material properties (Sun Shadows, ...) but won't render, so we do it here
  2187. UpdateMaterialPropertiesNow ();
  2188. }
  2189. if (_renderingInstancesCount == 1) {
  2190. // One instance, render directly to destination
  2191. fogRenderInstances [0].DoOnRenderImageInstance (source, destination);
  2192. } else {
  2193. RenderTextureDescriptor rtDesc = source.descriptor;
  2194. rtDesc.depthBufferBits = 0;
  2195. rtDesc.msaaSamples = 1;
  2196. //rtDesc.colorFormat = RenderTextureFormat.ARGB32; <-- causes banding issues with Linear Color space
  2197. RenderTexture rt1 = RenderTexture.GetTemporary (rtDesc);
  2198. fogRenderInstances [0].DoOnRenderImageInstance (source, rt1);
  2199. if (_renderingInstancesCount == 2) { // Two instance, render to intermediate, then to destination
  2200. fogRenderInstances [1].DoOnRenderImageInstance (rt1, destination);
  2201. }
  2202. if (_renderingInstancesCount >= 3) {
  2203. // 3 or more instances, render them and finally to destinatio
  2204. RenderTexture rt2 = RenderTexture.GetTemporary (rtDesc);
  2205. RenderTexture prev = rt1;
  2206. RenderTexture next = rt2;
  2207. int last = _renderingInstancesCount - 1;
  2208. for (int k = 1; k < last; k++) {
  2209. if (k > 1)
  2210. next.DiscardContents ();
  2211. fogRenderInstances [k].DoOnRenderImageInstance (prev, next);
  2212. if (next == rt2) {
  2213. prev = rt2;
  2214. next = rt1;
  2215. } else {
  2216. prev = rt1;
  2217. next = rt2;
  2218. }
  2219. }
  2220. fogRenderInstances [last].DoOnRenderImageInstance (prev, destination);
  2221. RenderTexture.ReleaseTemporary (rt2);
  2222. }
  2223. RenderTexture.ReleaseTemporary (rt1);
  2224. }
  2225. }
  2226. internal void DoOnRenderImageInstance (RenderTexture source, RenderTexture destination) {
  2227. if (mainCamera == null || fogMat == null) {
  2228. Graphics.Blit (source, destination);
  2229. return;
  2230. }
  2231. if (!_hasCamera) {
  2232. CheckFogAreaDimensions ();
  2233. if (_sunShadows && !fogRenderer.sunShadows) {
  2234. fogRenderer.sunShadows = true; // forces casting shadows on fog renderer
  2235. }
  2236. }
  2237. if (shouldUpdateMaterialProperties) {
  2238. UpdateMaterialPropertiesNow ();
  2239. }
  2240. if (Application.isPlaying) {
  2241. if (_useRealTime) {
  2242. deltaTime = Time.time - timeOfLastRender;
  2243. timeOfLastRender = Time.time;
  2244. } else {
  2245. deltaTime = Time.deltaTime;
  2246. }
  2247. UpdateWindSpeedQuick ();
  2248. }
  2249. if (_hasCamera) {
  2250. #if UNITY_EDITOR
  2251. if (_spsrBehaviour == SPSR_BEHAVIOUR.AutoDetectInEditor) {
  2252. #if UNITY_5_5_OR_NEWER
  2253. useSinglePassStereoRenderingMatrix = PlayerSettings.stereoRenderingPath == StereoRenderingPath.SinglePass;
  2254. #else
  2255. useSinglePassStereoRenderingMatrix = PlayerSettings.singlePassStereoRendering;
  2256. #endif
  2257. }
  2258. #endif
  2259. if (_spsrBehaviour == SPSR_BEHAVIOUR.ForcedOn && !_useSinglePassStereoRenderingMatrix) {
  2260. useSinglePassStereoRenderingMatrix = true;
  2261. } else if (_spsrBehaviour == SPSR_BEHAVIOUR.ForcedOff && _useSinglePassStereoRenderingMatrix) {
  2262. useSinglePassStereoRenderingMatrix = false;
  2263. }
  2264. }
  2265. if (fogRenderer.useSinglePassStereoRenderingMatrix && UnityEngine.XR.XRSettings.enabled) {
  2266. fogMat.SetMatrix ("_ClipToWorld", mainCamera.cameraToWorldMatrix);
  2267. } else {
  2268. fogMat.SetMatrix ("_ClipToWorld", mainCamera.cameraToWorldMatrix * mainCamera.projectionMatrix.inverse);
  2269. }
  2270. if (mainCamera.orthographic)
  2271. fogMat.SetVector ("_ClipDir", mainCamera.transform.forward);
  2272. if (fogRenderer.sun && _lightScatteringEnabled) {
  2273. UpdateScatteringData ();
  2274. }
  2275. // Updates point light illumination
  2276. for (int k = 0; k < MAX_POINT_LIGHTS; k++) {
  2277. Light pointLightComponent = pointLightComponents [k];
  2278. if (pointLightComponent != null) {
  2279. if (_pointLightColors [k] != pointLightComponent.color) {
  2280. _pointLightColors [k] = pointLightComponent.color;
  2281. isDirty = true;
  2282. }
  2283. if (_pointLightRanges [k] != pointLightComponent.range) {
  2284. _pointLightRanges [k] = pointLightComponent.range;
  2285. isDirty = true;
  2286. }
  2287. if (_pointLightPositions [k] != pointLightComponent.transform.position) {
  2288. _pointLightPositions [k] = pointLightComponent.transform.position;
  2289. isDirty = true;
  2290. }
  2291. if (_pointLightIntensities [k] != pointLightComponent.intensity) {
  2292. _pointLightIntensities [k] = pointLightComponent.intensity;
  2293. isDirty = true;
  2294. }
  2295. }
  2296. // if (_pointLightRanges [k] * _pointLightIntensities [k] > 0) {
  2297. SetMaterialLightData (k, pointLightComponent);
  2298. // }
  2299. }
  2300. // Render fog before transparent objects are drawn and only having into account the depth of opaque objects
  2301. if (_downsampling > 1f) {
  2302. int scaledWidth = GetScaledSize (source.width, _downsampling);
  2303. int scaledHeight = GetScaledSize (source.width, _downsampling);
  2304. RenderTextureDescriptor rtReducedDestinationDesc = source.descriptor;
  2305. rtReducedDestinationDesc.width = scaledWidth;
  2306. rtReducedDestinationDesc.height = scaledHeight;
  2307. rtReducedDestinationDesc.msaaSamples = 1;
  2308. reducedDestination = RenderTexture.GetTemporary (rtReducedDestinationDesc); // scaledWidth, scaledHeight, 0, RenderTextureFormat.ARGB32);
  2309. RenderTextureDescriptor rtReducedDepthDesc = source.descriptor;
  2310. rtReducedDepthDesc.width = scaledWidth;
  2311. rtReducedDepthDesc.height = scaledHeight;
  2312. rtReducedDepthDesc.msaaSamples = 1;
  2313. RenderTextureFormat rtFormat = SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.RFloat) ? RenderTextureFormat.RFloat : RenderTextureFormat.ARGBFloat;
  2314. rtReducedDestinationDesc.colorFormat = rtFormat;
  2315. RenderTexture reducedDepthTexture = RenderTexture.GetTemporary (rtReducedDestinationDesc); // scaledWidth, scaledHeight, 0, rtFormat);
  2316. if (_fogBlur) {
  2317. // RenderTexture rtBlur = RenderTexture.GetTemporary (rtReducedDestinationDesc); // scaledWidth, scaledHeight, 0, RenderTextureFormat.ARGB32);
  2318. // Graphics.Blit (source, rtBlur);
  2319. SetBlurTexture (source, rtReducedDestinationDesc);
  2320. // RenderTexture.ReleaseTemporary (rtBlur);
  2321. }
  2322. if (!_edgeImprove || UnityEngine.XR.XRSettings.enabled || SystemInfo.supportedRenderTargetCount < 2) {
  2323. Graphics.Blit (source, reducedDestination, fogMat, 3);
  2324. if (_edgeImprove)
  2325. Graphics.Blit (source, reducedDepthTexture, fogMat, 4);
  2326. } else {
  2327. fogMat.SetTexture ("_MainTex", source);
  2328. if (mrt == null)
  2329. mrt = new RenderBuffer[2];
  2330. mrt [0] = reducedDestination.colorBuffer;
  2331. mrt [1] = reducedDepthTexture.colorBuffer;
  2332. Graphics.SetRenderTarget (mrt, reducedDestination.depthBuffer);
  2333. Graphics.Blit (null, fogMat, 1);
  2334. }
  2335. fogMat.SetTexture ("_FogDownsampled", reducedDestination);
  2336. fogMat.SetTexture ("_DownsampledDepth", reducedDepthTexture);
  2337. Graphics.Blit (source, destination, fogMat, 2);
  2338. RenderTexture.ReleaseTemporary (reducedDepthTexture);
  2339. RenderTexture.ReleaseTemporary (reducedDestination);
  2340. } else {
  2341. if (_fogBlur) {
  2342. RenderTextureDescriptor rtReducedDestinationDesc = source.descriptor;
  2343. rtReducedDestinationDesc.width = 256;
  2344. rtReducedDestinationDesc.height = 256;
  2345. // RenderTexture rtBlur = RenderTexture.GetTemporary (rtReducedDestinationDesc); // 256, 256, 0, RenderTextureFormat.ARGB32);
  2346. // Graphics.Blit (source, rtBlur);
  2347. SetBlurTexture (source, rtReducedDestinationDesc);
  2348. // RenderTexture.ReleaseTemporary (rtBlur);
  2349. }
  2350. Graphics.Blit (source, destination, fogMat, 0);
  2351. }
  2352. }
  2353. int GetScaledSize (int size, float factor) {
  2354. size = (int)(size / factor);
  2355. size /= 4;
  2356. if (size < 1)
  2357. size = 1;
  2358. return size * 4;
  2359. }
  2360. #endregion
  2361. #region Transparency support
  2362. void CleanUpDepthTexture () {
  2363. if (depthTexture) {
  2364. RenderTexture.ReleaseTemporary (depthTexture);
  2365. depthTexture = null;
  2366. }
  2367. }
  2368. RenderTextureDescriptor defaultDesc;
  2369. void GetTransparentDepth () {
  2370. CleanUpDepthTexture ();
  2371. //if (defaultDesc.width == 0)
  2372. // return;
  2373. if (depthCam == null) {
  2374. if (depthCamObj == null) {
  2375. depthCamObj = GameObject.Find (DEPTH_CAM_NAME);
  2376. }
  2377. if (depthCamObj == null) {
  2378. depthCamObj = new GameObject (DEPTH_CAM_NAME);
  2379. depthCam = depthCamObj.AddComponent<Camera> ();
  2380. depthCam.enabled = false;
  2381. depthCamObj.hideFlags = HideFlags.HideAndDontSave;
  2382. } else {
  2383. depthCam = depthCamObj.GetComponent<Camera> ();
  2384. if (depthCam == null) {
  2385. DestroyImmediate (depthCamObj);
  2386. depthCamObj = null;
  2387. return;
  2388. }
  2389. }
  2390. }
  2391. depthCam.CopyFrom (mainCamera);
  2392. depthCam.depthTextureMode = DepthTextureMode.None;
  2393. depthTexture = RenderTexture.GetTemporary (mainCamera.pixelWidth, mainCamera.pixelHeight, 24, RenderTextureFormat.Depth, RenderTextureReadWrite.Linear);
  2394. depthCam.backgroundColor = new Color (0, 0, 0, 0);
  2395. depthCam.clearFlags = CameraClearFlags.SolidColor;
  2396. depthCam.cullingMask = _transparencyLayerMask;
  2397. depthCam.targetTexture = depthTexture;
  2398. depthCam.renderingPath = RenderingPath.Forward;
  2399. if (depthShader == null) {
  2400. depthShader = Shader.Find ("VolumetricFogAndMist/CopyDepth");
  2401. }
  2402. if (depthShaderAndTrans == null) {
  2403. depthShaderAndTrans = Shader.Find ("VolumetricFogAndMist/CopyDepthAndTrans");
  2404. }
  2405. switch (_computeDepthScope) {
  2406. case COMPUTE_DEPTH_SCOPE.OnlyTreeBillboards:
  2407. depthCam.RenderWithShader (depthShader, "RenderType");
  2408. break;
  2409. case COMPUTE_DEPTH_SCOPE.TreeBillboardsAndTransparentObjects:
  2410. depthCam.RenderWithShader (depthShaderAndTrans, "RenderType");
  2411. break;
  2412. default:
  2413. depthCam.RenderWithShader (depthShaderAndTrans, null);
  2414. break;
  2415. }
  2416. Shader.SetGlobalTexture ("_VolumetricFogDepthTexture", depthTexture);
  2417. }
  2418. #endregion
  2419. #region Shadow support
  2420. void CastSunShadows () {
  2421. if (!enabled || !gameObject.activeSelf || fogMat == null)
  2422. return;
  2423. if (_sunShadowsBakeMode == SUN_SHADOWS_BAKE_MODE.Discrete && _sunShadowsRefreshInterval > 0 && Time.time > lastShadowUpdateFrame + _sunShadowsRefreshInterval) {
  2424. needUpdateDepthSunTexture = true;
  2425. }
  2426. if (!Application.isPlaying || needUpdateDepthSunTexture || depthSunTexture == null || !depthSunTexture.IsCreated ()) {
  2427. needUpdateDepthSunTexture = false;
  2428. lastShadowUpdateFrame = Time.time;
  2429. GetSunShadows ();
  2430. }
  2431. }
  2432. void GetSunShadows () {
  2433. if (_sun == null || !_sunShadows)
  2434. return;
  2435. if (depthSunCam == null) {
  2436. if (depthSunCamObj == null) {
  2437. depthSunCamObj = GameObject.Find (DEPTH_SUN_CAM_NAME);
  2438. }
  2439. if (depthSunCamObj == null) {
  2440. depthSunCamObj = new GameObject (DEPTH_SUN_CAM_NAME);
  2441. depthSunCamObj.hideFlags = HideFlags.HideAndDontSave;
  2442. depthSunCam = depthSunCamObj.AddComponent<Camera> ();
  2443. } else {
  2444. depthSunCam = depthSunCamObj.GetComponent<Camera> ();
  2445. if (depthSunCam == null) {
  2446. DestroyImmediate (depthSunCamObj);
  2447. depthSunCamObj = null;
  2448. return;
  2449. }
  2450. }
  2451. if (depthSunShader == null) {
  2452. depthSunShader = Shader.Find ("VolumetricFogAndMist/CopySunDepth");
  2453. }
  2454. depthSunCam.SetReplacementShader (depthSunShader, "RenderType");
  2455. depthSunCam.nearClipPlane = 1f;
  2456. depthSunCam.renderingPath = RenderingPath.Forward;
  2457. depthSunCam.orthographic = true;
  2458. depthSunCam.aspect = 1f;
  2459. depthSunCam.backgroundColor = new Color (0, 0, 0.5f, 0);
  2460. depthSunCam.clearFlags = CameraClearFlags.SolidColor;
  2461. depthSunCam.depthTextureMode = DepthTextureMode.None;
  2462. }
  2463. float shadowOrthoSize = _sunShadowsMaxDistance / 0.95f;
  2464. const float farClip = 2000;
  2465. depthSunCam.transform.position = mainCamera.transform.position - _sun.transform.forward * farClip;
  2466. depthSunCam.transform.rotation = _sun.transform.rotation;
  2467. depthSunCam.farClipPlane = farClip * 2f;
  2468. depthSunCam.orthographicSize = shadowOrthoSize;
  2469. if (sunLight != null) {
  2470. depthSunCam.cullingMask = _sunShadowsLayerMask;
  2471. }
  2472. if (depthSunTexture == null) {
  2473. int shadowTexResolution = (int)Mathf.Pow (2, _sunShadowsResolution + 9);
  2474. depthSunTexture = new RenderTexture (shadowTexResolution, shadowTexResolution, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
  2475. depthSunTexture.hideFlags = HideFlags.DontSave;
  2476. depthSunTexture.filterMode = FilterMode.Point;
  2477. depthSunTexture.wrapMode = TextureWrapMode.Clamp;
  2478. depthSunTexture.Create ();
  2479. }
  2480. depthSunCam.targetTexture = depthSunTexture;
  2481. Shader.SetGlobalFloat ("_VF_ShadowBias", _sunShadowsBias);
  2482. if (Application.isPlaying && _sunShadowsBakeMode == SUN_SHADOWS_BAKE_MODE.Realtime) {
  2483. if (!depthSunCam.enabled) {
  2484. depthSunCam.enabled = true;
  2485. }
  2486. } else {
  2487. if (depthSunCam.enabled) {
  2488. depthSunCam.enabled = false;
  2489. }
  2490. depthSunCam.Render ();
  2491. }
  2492. Shader.SetGlobalMatrix ("_VolumetricFogSunProj", depthSunCam.projectionMatrix * depthSunCam.worldToCameraMatrix);
  2493. Shader.SetGlobalTexture ("_VolumetricFogSunDepthTexture", depthSunTexture);
  2494. Vector4 swp = depthSunCam.transform.position;
  2495. swp.w = Mathf.Min (_sunShadowsMaxDistance, _maxFogLength);
  2496. Shader.SetGlobalVector ("_VolumetricFogSunWorldPos", swp);
  2497. UpdateSunShadowsData ();
  2498. }
  2499. #endregion
  2500. #region Fog Blur support
  2501. void SetBlurTexture (RenderTexture source, RenderTextureDescriptor desc) {
  2502. if (blurMat == null) {
  2503. Shader blurShader = Shader.Find ("VolumetricFogAndMist/Blur");
  2504. blurMat = new Material (blurShader);
  2505. blurMat.hideFlags = HideFlags.DontSave;
  2506. }
  2507. if (blurMat == null)
  2508. return;
  2509. blurMat.SetFloat ("_BlurDepth", _fogBlurDepth);
  2510. RenderTexture temp1 = RenderTexture.GetTemporary (desc); // source.width, source.height, 0, source.format);
  2511. Graphics.Blit (source, temp1, blurMat, 0);
  2512. RenderTexture temp2 = RenderTexture.GetTemporary (desc); // source.width, source.height, 0, source.format);
  2513. Graphics.Blit (temp1, temp2, blurMat, 1);
  2514. blurMat.SetFloat ("_BlurDepth", _fogBlurDepth * 2f);
  2515. temp1.DiscardContents ();
  2516. Graphics.Blit (temp2, temp1, blurMat, 0);
  2517. temp2.DiscardContents ();
  2518. Graphics.Blit (temp1, temp2, blurMat, 1);
  2519. fogMat.SetTexture ("_BlurTex", temp2);
  2520. RenderTexture.ReleaseTemporary (temp2);
  2521. RenderTexture.ReleaseTemporary (temp1);
  2522. }
  2523. void DestroySunShadowsDependencies () {
  2524. if (depthSunCamObj != null) {
  2525. DestroyImmediate (depthSunCamObj);
  2526. depthSunCamObj = null;
  2527. }
  2528. CleanUpTextureDepthSun ();
  2529. }
  2530. void CleanUpTextureDepthSun () {
  2531. if (depthSunTexture != null) {
  2532. depthSunTexture.Release ();
  2533. depthSunTexture = null;
  2534. }
  2535. }
  2536. #endregion
  2537. #region Settings area
  2538. public string GetCurrentPresetName () {
  2539. return Enum.GetName (typeof(FOG_PRESET), _preset);
  2540. }
  2541. void UpdatePreset () {
  2542. switch (_preset) {
  2543. case FOG_PRESET.Clear:
  2544. _density = 0;
  2545. _fogOfWarEnabled = false;
  2546. _fogVoidRadius = 0;
  2547. break;
  2548. case FOG_PRESET.Mist:
  2549. _skySpeed = 0.3f;
  2550. _skyHaze = 15;
  2551. _skyNoiseStrength = 0.1f;
  2552. _skyAlpha = 0.8f;
  2553. _density = 0.3f;
  2554. _noiseStrength = 0.6f;
  2555. _noiseScale = 1;
  2556. _noiseSparse = 0f;
  2557. _distance = 0;
  2558. _distanceFallOff = 0f;
  2559. _height = 6;
  2560. _stepping = 8;
  2561. _steppingNear = 0;
  2562. _alpha = 1;
  2563. _color = new Color (0.89f, 0.89f, 0.89f, 1);
  2564. _skyColor = _color;
  2565. _specularColor = new Color (1, 1, 0.8f, 1);
  2566. _specularIntensity = 0.1f;
  2567. _specularThreshold = 0.6f;
  2568. _lightColor = Color.white;
  2569. _lightIntensity = 0.12f;
  2570. _speed = 0.01f;
  2571. _downsampling = 1;
  2572. _baselineRelativeToCamera = false;
  2573. CheckWaterLevel (false);
  2574. _fogVoidRadius = 0;
  2575. CopyTransitionValues ();
  2576. break;
  2577. case FOG_PRESET.WindyMist:
  2578. _skySpeed = 0.3f;
  2579. _skyHaze = 25;
  2580. _skyNoiseStrength = 0.1f;
  2581. _skyAlpha = 0.85f;
  2582. _density = 0.3f;
  2583. _noiseStrength = 0.5f;
  2584. _noiseScale = 1.15f;
  2585. _noiseSparse = 0f;
  2586. _distance = 0;
  2587. _distanceFallOff = 0f;
  2588. _height = 6.5f;
  2589. _stepping = 10;
  2590. _steppingNear = 0;
  2591. _alpha = 1;
  2592. _color = new Color (0.89f, 0.89f, 0.89f, 1);
  2593. _skyColor = _color;
  2594. _specularColor = new Color (1, 1, 0.8f, 1);
  2595. _specularIntensity = 0.1f;
  2596. _specularThreshold = 0.6f;
  2597. _lightColor = Color.white;
  2598. _lightIntensity = 0;
  2599. _speed = 0.15f;
  2600. _downsampling = 1;
  2601. _baselineRelativeToCamera = false;
  2602. CheckWaterLevel (false);
  2603. _fogVoidRadius = 0;
  2604. CopyTransitionValues ();
  2605. break;
  2606. case FOG_PRESET.GroundFog:
  2607. _skySpeed = 0.3f;
  2608. _skyHaze = 0;
  2609. _skyNoiseStrength = 0.1f;
  2610. _skyAlpha = 0.85f;
  2611. _density = 0.6f;
  2612. _noiseStrength = 0.479f;
  2613. _noiseScale = 1.15f;
  2614. _noiseSparse = 0f;
  2615. _distance = 5;
  2616. _distanceFallOff = 1f;
  2617. _height = 1.5f;
  2618. _stepping = 8;
  2619. _steppingNear = 0;
  2620. _alpha = 0.95f;
  2621. _color = new Color (0.89f, 0.89f, 0.89f, 1);
  2622. _skyColor = _color;
  2623. _specularColor = new Color (1, 1, 0.8f, 1);
  2624. _specularIntensity = 0.2f;
  2625. _specularThreshold = 0.6f;
  2626. _lightColor = Color.white;
  2627. _lightIntensity = 0.2f;
  2628. _speed = 0.01f;
  2629. _downsampling = 1;
  2630. _baselineRelativeToCamera = false;
  2631. CheckWaterLevel (false);
  2632. _fogVoidRadius = 0;
  2633. CopyTransitionValues ();
  2634. break;
  2635. case FOG_PRESET.FrostedGround:
  2636. _skySpeed = 0;
  2637. _skyHaze = 0;
  2638. _skyNoiseStrength = 0.729f;
  2639. _skyAlpha = 0.55f;
  2640. _density = 1;
  2641. _noiseStrength = 0.164f;
  2642. _noiseScale = 1.81f;
  2643. _noiseSparse = 0f;
  2644. _distance = 0;
  2645. _distanceFallOff = 0;
  2646. _height = 0.5f;
  2647. _stepping = 20;
  2648. _steppingNear = 50;
  2649. _alpha = 0.97f;
  2650. _color = new Color (0.546f, 0.648f, 0.710f, 1);
  2651. _skyColor = _color;
  2652. _specularColor = new Color (0.792f, 0.792f, 0.792f, 1);
  2653. _specularIntensity = 1;
  2654. _specularThreshold = 0.866f;
  2655. _lightColor = new Color (0.972f, 0.972f, 0.972f, 1);
  2656. _lightIntensity = 0.743f;
  2657. _speed = 0;
  2658. _downsampling = 1;
  2659. _baselineRelativeToCamera = false;
  2660. CheckWaterLevel (false);
  2661. _fogVoidRadius = 0;
  2662. CopyTransitionValues ();
  2663. break;
  2664. case FOG_PRESET.FoggyLake:
  2665. _skySpeed = 0.3f;
  2666. _skyHaze = 40;
  2667. _skyNoiseStrength = 0.574f;
  2668. _skyAlpha = 0.827f;
  2669. _density = 1;
  2670. _noiseStrength = 0.03f;
  2671. _noiseScale = 5.77f;
  2672. _noiseSparse = 0f;
  2673. _distance = 0;
  2674. _distanceFallOff = 0;
  2675. _height = 4;
  2676. _stepping = 6;
  2677. _steppingNear = 14.4f;
  2678. _alpha = 1;
  2679. _color = new Color (0, 0.960f, 1, 1);
  2680. _skyColor = _color;
  2681. _specularColor = Color.white;
  2682. _lightColor = Color.white;
  2683. _specularIntensity = 0.861f;
  2684. _specularThreshold = 0.907f;
  2685. _lightIntensity = 0.126f;
  2686. _speed = 0;
  2687. _downsampling = 1;
  2688. _baselineRelativeToCamera = false;
  2689. CheckWaterLevel (false);
  2690. _fogVoidRadius = 0;
  2691. CopyTransitionValues ();
  2692. break;
  2693. case FOG_PRESET.LowClouds:
  2694. _skySpeed = 0.3f;
  2695. _skyHaze = 60;
  2696. _skyNoiseStrength = 1f;
  2697. _skyAlpha = 0.96f;
  2698. _density = 1;
  2699. _noiseStrength = 0.7f;
  2700. _noiseScale = 1;
  2701. _noiseSparse = 0f;
  2702. _distance = 0;
  2703. _distanceFallOff = 0;
  2704. _height = 4f;
  2705. _stepping = 12;
  2706. _steppingNear = 0;
  2707. _alpha = 0.98f;
  2708. _color = new Color (0.89f, 0.89f, 0.89f, 1);
  2709. _skyColor = _color;
  2710. _specularColor = new Color (1, 1, 0.8f, 1);
  2711. _specularIntensity = 0.15f;
  2712. _specularThreshold = 0.6f;
  2713. _lightColor = Color.white;
  2714. _lightIntensity = 0.15f;
  2715. _speed = 0.008f;
  2716. _downsampling = 1;
  2717. _baselineRelativeToCamera = false;
  2718. CheckWaterLevel (false);
  2719. _fogVoidRadius = 0;
  2720. CopyTransitionValues ();
  2721. break;
  2722. case FOG_PRESET.SeaClouds:
  2723. _skySpeed = 0.3f;
  2724. _skyHaze = 60;
  2725. _skyNoiseStrength = 1f;
  2726. _skyAlpha = 0.96f;
  2727. _density = 1;
  2728. _noiseStrength = 1;
  2729. _noiseScale = 1.5f;
  2730. _noiseSparse = 0f;
  2731. _distance = 0;
  2732. _distanceFallOff = 0;
  2733. _height = 12.4f;
  2734. _stepping = 6;
  2735. _alpha = 0.98f;
  2736. _color = new Color (0.89f, 0.89f, 0.89f, 1);
  2737. _skyColor = _color;
  2738. _specularColor = new Color (1, 1, 0.8f, 1);
  2739. _specularIntensity = 0.259f;
  2740. _specularThreshold = 0.6f;
  2741. _lightColor = Color.white;
  2742. _lightIntensity = 0.15f;
  2743. _speed = 0.008f;
  2744. _downsampling = 1;
  2745. _baselineRelativeToCamera = false;
  2746. CheckWaterLevel (false);
  2747. _fogVoidRadius = 0;
  2748. CopyTransitionValues ();
  2749. break;
  2750. case FOG_PRESET.Fog:
  2751. _skySpeed = 0.3f;
  2752. _skyHaze = 144;
  2753. _skyNoiseStrength = 0.7f;
  2754. _skyAlpha = 0.9f;
  2755. _density = 0.35f;
  2756. _noiseStrength = 0.3f;
  2757. _noiseScale = 1;
  2758. _noiseSparse = 0f;
  2759. _distance = 20;
  2760. _distanceFallOff = 0.7f;
  2761. _height = 8;
  2762. _stepping = 8;
  2763. _steppingNear = 0;
  2764. _alpha = 0.97f;
  2765. _color = new Color (0.89f, 0.89f, 0.89f, 1);
  2766. _skyColor = _color;
  2767. _specularColor = new Color (1, 1, 0.8f, 1);
  2768. _specularIntensity = 0;
  2769. _specularThreshold = 0.6f;
  2770. _lightColor = Color.white;
  2771. _lightIntensity = 0;
  2772. _speed = 0.05f;
  2773. _downsampling = 1;
  2774. _baselineRelativeToCamera = false;
  2775. CheckWaterLevel (false);
  2776. _fogVoidRadius = 0;
  2777. CopyTransitionValues ();
  2778. break;
  2779. case FOG_PRESET.HeavyFog:
  2780. _skySpeed = 0.05f;
  2781. _skyHaze = 500;
  2782. _skyNoiseStrength = 0.96f;
  2783. _skyAlpha = 1;
  2784. _density = 0.35f;
  2785. _noiseStrength = 0.1f;
  2786. _noiseScale = 1;
  2787. _noiseSparse = 0f;
  2788. _distance = 20;
  2789. _distanceFallOff = 0.8f;
  2790. _height = 18;
  2791. _stepping = 6;
  2792. _steppingNear = 0;
  2793. _alpha = 1;
  2794. _color = new Color (0.91f, 0.91f, 0.91f, 1);
  2795. _skyColor = _color;
  2796. _specularColor = new Color (1, 1, 0.8f, 1);
  2797. _specularIntensity = 0;
  2798. _specularThreshold = 0.6f;
  2799. _lightColor = Color.white;
  2800. _lightIntensity = 0;
  2801. _speed = 0.015f;
  2802. _downsampling = 1;
  2803. _baselineRelativeToCamera = false;
  2804. CheckWaterLevel (false);
  2805. _fogVoidRadius = 0;
  2806. CopyTransitionValues ();
  2807. break;
  2808. case FOG_PRESET.SandStorm1:
  2809. _skySpeed = 0.35f;
  2810. _skyHaze = 388;
  2811. _skyNoiseStrength = 0.847f;
  2812. _skyAlpha = 1;
  2813. _density = 0.487f;
  2814. _noiseStrength = 0.758f;
  2815. _noiseScale = 1.71f;
  2816. _noiseSparse = 0f;
  2817. _distance = 0;
  2818. _distanceFallOff = 0;
  2819. _height = 16;
  2820. _stepping = 6;
  2821. _steppingNear = 0;
  2822. _alpha = 1;
  2823. _color = new Color (0.505f, 0.505f, 0.505f, 1);
  2824. _skyColor = _color;
  2825. _specularColor = new Color (1, 1, 0.8f, 1);
  2826. _specularIntensity = 0;
  2827. _specularThreshold = 0.6f;
  2828. _lightColor = Color.white;
  2829. _lightIntensity = 0;
  2830. _speed = 0.3f;
  2831. _windDirection = Vector3.right;
  2832. _downsampling = 1;
  2833. _baselineRelativeToCamera = false;
  2834. CheckWaterLevel (false);
  2835. _fogVoidRadius = 0;
  2836. CopyTransitionValues ();
  2837. break;
  2838. case FOG_PRESET.Smoke:
  2839. _skySpeed = 0.109f;
  2840. _skyHaze = 10;
  2841. _skyNoiseStrength = 0.119f;
  2842. _skyAlpha = 1;
  2843. _density = 1;
  2844. _noiseStrength = 0.767f;
  2845. _noiseScale = 1.6f;
  2846. _noiseSparse = 0f;
  2847. _distance = 0;
  2848. _distanceFallOff = 0f;
  2849. _height = 8;
  2850. _stepping = 12;
  2851. _steppingNear = 25;
  2852. _alpha = 1;
  2853. _color = new Color (0.125f, 0.125f, 0.125f, 1);
  2854. _skyColor = _color;
  2855. _specularColor = new Color (1, 1, 1, 1);
  2856. _specularIntensity = 0.575f;
  2857. _specularThreshold = 0.6f;
  2858. _lightColor = Color.white;
  2859. _lightIntensity = 1;
  2860. _speed = 0.075f;
  2861. _windDirection = Vector3.right;
  2862. _downsampling = 1;
  2863. _baselineRelativeToCamera = false;
  2864. CheckWaterLevel (false);
  2865. _baselineHeight += 8f;
  2866. _fogVoidRadius = 0;
  2867. CopyTransitionValues ();
  2868. break;
  2869. case FOG_PRESET.ToxicSwamp:
  2870. _skySpeed = 0.062f;
  2871. _skyHaze = 22;
  2872. _skyNoiseStrength = 0.694f;
  2873. _skyAlpha = 1;
  2874. _density = 1;
  2875. _noiseStrength = 1;
  2876. _noiseScale = 1;
  2877. _noiseSparse = 0f;
  2878. _distance = 0;
  2879. _distanceFallOff = 0;
  2880. _height = 2.5f;
  2881. _stepping = 20;
  2882. _steppingNear = 50;
  2883. _alpha = 0.95f;
  2884. _color = new Color (0.0238f, 0.175f, 0.109f, 1);
  2885. _skyColor = _color;
  2886. _specularColor = new Color (0.593f, 0.625f, 0.207f, 1);
  2887. _specularIntensity = 0.735f;
  2888. _specularThreshold = 0.6f;
  2889. _lightColor = new Color (0.730f, 0.746f, 0.511f, 1);
  2890. _lightIntensity = 0.492f;
  2891. _speed = 0.0003f;
  2892. _windDirection = Vector3.right;
  2893. _downsampling = 1;
  2894. _baselineRelativeToCamera = false;
  2895. CheckWaterLevel (false);
  2896. _fogVoidRadius = 0;
  2897. CopyTransitionValues ();
  2898. break;
  2899. case FOG_PRESET.SandStorm2:
  2900. _skySpeed = 0;
  2901. _skyHaze = 0;
  2902. _skyNoiseStrength = 0.729f;
  2903. _skyAlpha = 0.55f;
  2904. _density = 0.545f;
  2905. _noiseStrength = 1;
  2906. _noiseScale = 3;
  2907. _noiseSparse = 0f;
  2908. _distance = 0;
  2909. _distanceFallOff = 0;
  2910. _height = 12;
  2911. _stepping = 5;
  2912. _steppingNear = 19.6f;
  2913. _alpha = 0.96f;
  2914. _color = new Color (0.609f, 0.609f, 0.609f, 1);
  2915. _skyColor = _color;
  2916. _specularColor = new Color (0.589f, 0.621f, 0.207f, 1);
  2917. _specularIntensity = 0.505f;
  2918. _specularThreshold = 0.6f;
  2919. _lightColor = new Color (0.726f, 0.742f, 0.507f, 1);
  2920. _lightIntensity = 0.581f;
  2921. _speed = 0.168f;
  2922. _windDirection = Vector3.right;
  2923. _downsampling = 1;
  2924. _baselineRelativeToCamera = false;
  2925. CheckWaterLevel (false);
  2926. _fogVoidRadius = 0;
  2927. CopyTransitionValues ();
  2928. break;
  2929. case FOG_PRESET.WorldEdge:
  2930. _skySpeed = 0.3f;
  2931. _skyHaze = 60;
  2932. _skyNoiseStrength = 1f;
  2933. _skyAlpha = 0.96f;
  2934. _density = 1;
  2935. _noiseStrength = 1;
  2936. _noiseScale = 3f;
  2937. _noiseSparse = 0f;
  2938. _distance = 0;
  2939. _distanceFallOff = 0;
  2940. _height = 20f;
  2941. _stepping = 6;
  2942. _alpha = 0.98f;
  2943. _color = new Color (0.89f, 0.89f, 0.89f, 1);
  2944. _skyColor = _color;
  2945. _specularColor = new Color (1, 1, 0.8f, 1);
  2946. _specularIntensity = 0.259f;
  2947. _specularThreshold = 0.6f;
  2948. _lightColor = Color.white;
  2949. _lightIntensity = 0.15f;
  2950. _speed = 0.03f;
  2951. _downsampling = 2;
  2952. _baselineRelativeToCamera = false;
  2953. CheckWaterLevel (false);
  2954. Terrain terrain = GetActiveTerrain ();
  2955. if (terrain != null) {
  2956. _fogVoidPosition = terrain.transform.position + terrain.terrainData.size * 0.5f;
  2957. _fogVoidRadius = terrain.terrainData.size.x * 0.45f;
  2958. _fogVoidHeight = terrain.terrainData.size.y;
  2959. _fogVoidDepth = terrain.terrainData.size.z * 0.45f;
  2960. _fogVoidFallOff = 6f;
  2961. _fogAreaRadius = 0;
  2962. _character = null;
  2963. _fogAreaCenter = null;
  2964. float terrainSize = terrain.terrainData.size.x;
  2965. if (mainCamera.farClipPlane < terrainSize)
  2966. mainCamera.farClipPlane = terrainSize;
  2967. if (_maxFogLength < terrainSize * 0.6f)
  2968. _maxFogLength = terrainSize * 0.6f;
  2969. }
  2970. CopyTransitionValues ();
  2971. break;
  2972. }
  2973. FogOfWarUpdateTexture ();
  2974. UpdateMaterialProperties ();
  2975. UpdateRenderComponents ();
  2976. UpdateTextureAlpha ();
  2977. UpdateTexture ();
  2978. }
  2979. public void CheckWaterLevel (bool baseZero) {
  2980. if (mainCamera == null)
  2981. return;
  2982. if (_baselineHeight > mainCamera.transform.position.y || baseZero)
  2983. _baselineHeight = 0;
  2984. #if GAIA_PRESENT
  2985. GaiaSceneInfo sceneInfo = GaiaSceneInfo.GetSceneInfo();
  2986. _baselineHeight = sceneInfo.m_seaLevel;
  2987. #else
  2988. // Finds water
  2989. GameObject water = GameObject.Find ("Water");
  2990. if (water == null) {
  2991. GameObject[] gos = GameObject.FindObjectsOfType<GameObject> ();
  2992. for (int k = 0; k < gos.Length; k++) {
  2993. if (gos [k] != null && gos [k].layer == 4) {
  2994. water = gos [k];
  2995. break;
  2996. }
  2997. }
  2998. }
  2999. if (water != null) {
  3000. _renderBeforeTransparent = false; // adds compatibility with water
  3001. if (_baselineHeight < water.transform.position.y)
  3002. _baselineHeight = water.transform.position.y;
  3003. }
  3004. #endif
  3005. UpdateMaterialHeights ();
  3006. }
  3007. /// <summary>
  3008. /// Get the currently active terrain - or any terrain
  3009. /// </summary>
  3010. /// <returns>A terrain if there is one</returns>
  3011. public static Terrain GetActiveTerrain () {
  3012. //Grab active terrain if we can
  3013. Terrain terrain = Terrain.activeTerrain;
  3014. if (terrain != null && terrain.isActiveAndEnabled) {
  3015. return terrain;
  3016. }
  3017. //Then check rest of terrains
  3018. for (int idx = 0; idx < Terrain.activeTerrains.Length; idx++) {
  3019. terrain = Terrain.activeTerrains [idx];
  3020. if (terrain != null && terrain.isActiveAndEnabled) {
  3021. return terrain;
  3022. }
  3023. }
  3024. return null;
  3025. }
  3026. void UpdateMaterialFogColor () {
  3027. fogMat.SetColor ("_Color", currentFogColor * 2.0f);
  3028. }
  3029. void UpdateMaterialHeights () {
  3030. currentFogAltitude = _baselineHeight;
  3031. Vector3 adjustedFogAreaPosition = _fogAreaPosition;
  3032. if (_fogAreaRadius > 0) {
  3033. if (_fogAreaCenter != null && _fogAreaFollowMode == FOG_AREA_FOLLOW_MODE.FullXYZ) {
  3034. currentFogAltitude += _fogAreaCenter.transform.position.y;
  3035. }
  3036. adjustedFogAreaPosition.y = 0; // baseHeight;
  3037. }
  3038. if (_baselineRelativeToCamera && !_useXYPlane) {
  3039. oldBaselineRelativeCameraY += (mainCamera.transform.position.y - oldBaselineRelativeCameraY) * Mathf.Clamp01 (1.001f - _baselineRelativeToCameraDelay);
  3040. currentFogAltitude += oldBaselineRelativeCameraY - 1f;
  3041. }
  3042. float scale = 0.01f / _noiseScale;
  3043. fogMat.SetVector ("_FogData", new Vector4 (currentFogAltitude, _height, 1.0f / _density, scale));
  3044. fogMat.SetFloat ("_FogSkyHaze", _skyHaze + currentFogAltitude);
  3045. Vector3 v = _fogVoidPosition - currentFogAltitude * Vector3.up;
  3046. fogMat.SetVector ("_FogVoidPosition", v);
  3047. fogMat.SetVector ("_FogAreaPosition", adjustedFogAreaPosition);
  3048. }
  3049. void UpdateMaterialProperties () {
  3050. shouldUpdateMaterialProperties = true;
  3051. if (!Application.isPlaying)
  3052. UpdateMaterialPropertiesNow ();
  3053. }
  3054. void UpdateMaterialPropertiesNow () {
  3055. if (fogMat == null)
  3056. return;
  3057. shouldUpdateMaterialProperties = false;
  3058. #if UNITY_EDITOR
  3059. #if UNITY_5_5_OR_NEWER
  3060. _useSinglePassStereoRenderingMatrix = PlayerSettings.stereoRenderingPath == StereoRenderingPath.SinglePass;
  3061. #elif UNITY_5_4_OR_NEWER
  3062. _useSinglePassStereoRenderingMatrix = PlayerSettings.singlePassStereoRendering;
  3063. #endif
  3064. #endif
  3065. UpdateSkyColor (_skyAlpha);
  3066. Vector4 fogStepping = new Vector4 (1.0f / (_stepping + 1.0f), 1 / (1 + _steppingNear), _edgeThreshold, _dithering ? _ditherStrength * 0.1f : 0f);
  3067. fogMat.SetFloat ("_Jitter", _jitterStrength);
  3068. if (!_edgeImprove)
  3069. fogStepping.z = 0;
  3070. fogMat.SetVector ("_FogStepping", fogStepping);
  3071. fogMat.SetFloat ("_FogAlpha", currentFogAlpha);
  3072. UpdateMaterialHeights ();
  3073. float scale = 0.01f / _noiseScale;
  3074. float maxFogLengthFallOff = _maxFogLength * _maxFogLengthFallOff + 1.0f;
  3075. fogMat.SetVector ("_FogDistance", new Vector4 (scale * scale * _distance * _distance, (_distanceFallOff * _distanceFallOff + 0.1f), _maxFogLength, maxFogLengthFallOff)); //, _distance * (1.0f - _distanceFallOff)));
  3076. UpdateMaterialFogColor ();
  3077. // enable shader options
  3078. if (shaderKeywords == null) {
  3079. shaderKeywords = new List<string> ();
  3080. } else {
  3081. shaderKeywords.Clear ();
  3082. }
  3083. if (_distance > 0)
  3084. shaderKeywords.Add (SKW_FOG_DISTANCE_ON);
  3085. if (_fogVoidRadius > 0 && _fogVoidFallOff > 0) {
  3086. Vector4 voidData = new Vector4 (1.0f / (1.0f + _fogVoidRadius), 1.0f / (1.0f + _fogVoidHeight), 1.0f / (1.0f + _fogVoidDepth), _fogVoidFallOff);
  3087. if (_fogVoidTopology == FOG_VOID_TOPOLOGY.Box) {
  3088. shaderKeywords.Add (SKW_FOG_VOID_BOX);
  3089. } else {
  3090. shaderKeywords.Add (SKW_FOG_VOID_SPHERE);
  3091. }
  3092. fogMat.SetVector ("_FogVoidData", voidData);
  3093. }
  3094. if (_fogAreaRadius > 0 && _fogAreaFallOff > 0) {
  3095. Vector4 areaData = new Vector4 (1.0f / (0.0001f + _fogAreaRadius), 1.0f / (0.0001f + _fogAreaHeight), 1.0f / (0.0001f + _fogAreaDepth), _fogAreaFallOff);
  3096. if (_fogAreaTopology == FOG_AREA_TOPOLOGY.Box) {
  3097. shaderKeywords.Add (SKW_FOG_AREA_BOX);
  3098. } else {
  3099. shaderKeywords.Add (SKW_FOG_AREA_SPHERE);
  3100. areaData.y = _fogAreaRadius * _fogAreaRadius;
  3101. areaData.x /= scale;
  3102. areaData.z /= scale;
  3103. }
  3104. fogMat.SetVector ("_FogAreaData", areaData);
  3105. }
  3106. if (_skyHaze > 0 && _skyAlpha > 0 && !_useXYPlane) {
  3107. shaderKeywords.Add (SKW_FOG_HAZE_ON);
  3108. }
  3109. if (_fogOfWarEnabled) {
  3110. shaderKeywords.Add (SKW_FOG_OF_WAR_ON);
  3111. fogMat.SetTexture ("_FogOfWar", fogOfWarTexture);
  3112. fogMat.SetVector ("_FogOfWarCenter", _fogOfWarCenter);
  3113. fogMat.SetVector ("_FogOfWarSize", _fogOfWarSize);
  3114. Vector3 ca = _fogOfWarCenter - 0.5f * _fogOfWarSize;
  3115. if (_useXYPlane) {
  3116. fogMat.SetVector ("_FogOfWarCenterAdjusted", new Vector3 (ca.x / _fogOfWarSize.x, ca.y / (_fogOfWarSize.y + 0.0001f), 1f));
  3117. } else {
  3118. fogMat.SetVector ("_FogOfWarCenterAdjusted", new Vector3 (ca.x / _fogOfWarSize.x, 1f, ca.z / (_fogOfWarSize.z + 0.0001f)));
  3119. }
  3120. }
  3121. int pointLightCount = -1;
  3122. for (int k = 0; k < MAX_POINT_LIGHTS; k++) {
  3123. if (_pointLights [k] != null || _pointLightRanges [k] * _pointLightIntensities [k] > 0) {
  3124. pointLightCount = k;
  3125. }
  3126. }
  3127. if (pointLightCount >= 0) {
  3128. shaderKeywords.Add ("FOG_POINT_LIGHT" + pointLightCount.ToString ());
  3129. }
  3130. if (fogRenderer.sun) {
  3131. UpdateScatteringData ();
  3132. if (_lightScatteringEnabled) {
  3133. if (_lightScatteringExposure > 0) {
  3134. shaderKeywords.Add (SKW_LIGHT_SCATTERING);
  3135. }
  3136. }
  3137. if (_sunShadows) {
  3138. shaderKeywords.Add (SKW_SUN_SHADOWS);
  3139. UpdateSunShadowsData ();
  3140. }
  3141. }
  3142. if (_fogBlur) {
  3143. shaderKeywords.Add (SKW_FOG_BLUR);
  3144. fogMat.SetFloat ("_FogBlurDepth", _fogBlurDepth);
  3145. }
  3146. if (_useXYPlane) {
  3147. shaderKeywords.Add (SKW_FOG_USE_XY_PLANE);
  3148. }
  3149. if (fogRenderer.computeDepth) {
  3150. shaderKeywords.Add (SKW_FOG_COMPUTE_DEPTH);
  3151. }
  3152. fogMat.shaderKeywords = shaderKeywords.ToArray ();
  3153. if (_computeDepth && _computeDepthScope == COMPUTE_DEPTH_SCOPE.TreeBillboardsAndTransparentObjects) {
  3154. Shader.SetGlobalFloat ("_VFM_CutOff", _transparencyCutOff);
  3155. }
  3156. }
  3157. void UpdateSunShadowsData () {
  3158. if (_sun == null || !_sunShadows || fogMat == null)
  3159. return;
  3160. float shadowStrength = _sunShadowsStrength * Mathf.Clamp01 ((-_sun.transform.forward.y) * 10f);
  3161. if (shadowStrength < 0) {
  3162. shadowStrength = 0;
  3163. }
  3164. if (shadowStrength > 0 && !fogMat.IsKeywordEnabled (SKW_SUN_SHADOWS)) {
  3165. fogMat.EnableKeyword (SKW_SUN_SHADOWS);
  3166. } else if (shadowStrength <= 0 && fogMat.IsKeywordEnabled (SKW_SUN_SHADOWS)) {
  3167. fogMat.DisableKeyword (SKW_SUN_SHADOWS);
  3168. }
  3169. if (_hasCamera) {
  3170. Shader.SetGlobalVector ("_VolumetricFogSunShadowsData", new Vector4 (shadowStrength, _sunShadowsJitterStrength, _sunShadowsCancellation, 0));
  3171. }
  3172. }
  3173. void UpdateWindSpeedQuick () {
  3174. if (fogMat == null)
  3175. return;
  3176. // fog speed
  3177. float scale = 0.01f / _noiseScale;
  3178. windSpeedAcum += deltaTime * _windDirection * _speed / scale;
  3179. fogMat.SetVector ("_FogWindDir", windSpeedAcum);
  3180. // sky speed
  3181. skyHazeSpeedAcum += deltaTime * _skySpeed / 20f;
  3182. fogMat.SetVector ("_FogSkyData", new Vector4 (_skyHaze, _skyNoiseStrength, skyHazeSpeedAcum, _skyDepth));
  3183. }
  3184. void UpdateScatteringData () {
  3185. Vector3 viewportPos = mainCamera.WorldToViewportPoint (fogRenderer.sun.transform.forward * 10000f);
  3186. if (viewportPos.z < 0) {
  3187. Vector2 screenSunPos = new Vector2 (viewportPos.x, viewportPos.y);
  3188. float night = Mathf.Clamp01 (1.0f - _lightDirection.y);
  3189. if (screenSunPos != oldSunPos) {
  3190. oldSunPos = screenSunPos;
  3191. fogMat.SetVector ("_SunPosition", screenSunPos);
  3192. sunFade = Mathf.SmoothStep (1, 0, (screenSunPos - Vector2.one * 0.5f).magnitude * 0.5f) * night;
  3193. }
  3194. if (_lightScatteringEnabled && !fogMat.IsKeywordEnabled (SKW_LIGHT_SCATTERING)) {
  3195. fogMat.EnableKeyword (SKW_LIGHT_SCATTERING);
  3196. }
  3197. float intensity = _lightScatteringExposure * sunFade;
  3198. fogMat.SetVector ("_FogScatteringData", new Vector4 (_lightScatteringSpread / _lightScatteringSamples, intensity > 0 ? _lightScatteringSamples : 0, intensity, _lightScatteringWeight / (float)_lightScatteringSamples));
  3199. fogMat.SetVector ("_FogScatteringData2", new Vector4 (_lightScatteringIllumination, _lightScatteringDecay, _lightScatteringJittering, _lightScatteringEnabled ? 1.2f * _lightScatteringDiffusion * night * sunLightIntensity : 0));
  3200. fogMat.SetVector ("_SunDir", -_lightDirection);
  3201. fogMat.SetColor ("_SunColor", _lightColor);
  3202. } else {
  3203. if (fogMat.IsKeywordEnabled (SKW_LIGHT_SCATTERING)) {
  3204. fogMat.DisableKeyword (SKW_LIGHT_SCATTERING);
  3205. }
  3206. }
  3207. }
  3208. void UpdateSun () {
  3209. if (fogRenderer.sun != null) {
  3210. sunLight = fogRenderer.sun.GetComponent<Light> ();
  3211. } else {
  3212. sunLight = null;
  3213. }
  3214. }
  3215. void UpdateSkyColor (float alpha) {
  3216. if (fogMat == null)
  3217. return;
  3218. float skyIntensity = (_lightIntensity + sunLightIntensity) * Mathf.Clamp01 (1.0f - _lightDirection.y);
  3219. if (skyIntensity < 0)
  3220. skyIntensity = 0;
  3221. else if (skyIntensity > 1f)
  3222. skyIntensity = 1f;
  3223. _skyColor.a = alpha;
  3224. Color skyColorAdj = skyIntensity * _skyColor;
  3225. fogMat.SetColor ("_FogSkyColor", skyColorAdj);
  3226. }
  3227. void UpdatePointLights () {
  3228. for (int k = 0; k < _pointLights.Length; k++) {
  3229. GameObject pointLight = _pointLights [k];
  3230. if (pointLight != null) {
  3231. pointLightComponents [k] = pointLight.GetComponent<Light> ();
  3232. } else {
  3233. pointLightComponents [k] = null;
  3234. }
  3235. }
  3236. }
  3237. #endregion
  3238. #region Noise texture work
  3239. void UpdateTextureAlpha () {
  3240. // Precompute fog height into alpha channel
  3241. if (adjustedColors == null)
  3242. return;
  3243. float fogNoise = Mathf.Clamp (_noiseStrength, 0, 0.95f); // clamped to prevent flat fog on top
  3244. for (int k = 0; k < adjustedColors.Length; k++) {
  3245. float t = 1.0f - (_noiseSparse + noiseColors [k].b) * fogNoise;
  3246. t *= _density * _noiseFinalMultiplier;
  3247. if (t < 0)
  3248. t = 0;
  3249. else if (t > 1)
  3250. t = 1f;
  3251. adjustedColors [k].a = t;
  3252. }
  3253. hasChangeAdjustedColorsAlpha = true;
  3254. }
  3255. void UpdateTexture () {
  3256. if (fogMat == null)
  3257. return;
  3258. // Check Sun position
  3259. UpdateSkyColor (_skyAlpha);
  3260. // Precompute light color
  3261. float fogIntensity = (_lightIntensity + sunLightIntensity);
  3262. if (!_useXYPlane) {
  3263. fogIntensity *= Mathf.Clamp01 (1.0f - _lightDirection.y * 2.0f); // simulates sunset
  3264. }
  3265. switch (_lightingModel) {
  3266. default:
  3267. Color ambientMultiplied = RenderSettings.ambientLight * RenderSettings.ambientIntensity;
  3268. updatingTextureLightColor = Color.Lerp (ambientMultiplied, currentLightColor * fogIntensity, fogIntensity);
  3269. lastRenderSettingsAmbientLight = RenderSettings.ambientLight;
  3270. lastRenderSettingsAmbientIntensity = RenderSettings.ambientIntensity;
  3271. break;
  3272. case LIGHTING_MODEL.Natural:
  3273. Color ambient = RenderSettings.ambientLight;
  3274. lastRenderSettingsAmbientLight = RenderSettings.ambientLight;
  3275. updatingTextureLightColor = Color.Lerp (ambient, currentLightColor * fogIntensity + ambient, _lightIntensity);
  3276. break;
  3277. case LIGHTING_MODEL.SingleLight:
  3278. updatingTextureLightColor = Color.Lerp (Color.black, currentLightColor * fogIntensity, _lightIntensity);
  3279. break;
  3280. }
  3281. if (Application.isPlaying) { // && !hasChangeAdjustedColorsAlpha) {
  3282. updatingTextureSlice = 0;
  3283. } else {
  3284. updatingTextureSlice = -1;
  3285. }
  3286. UpdateTextureColors (adjustedColors, hasChangeAdjustedColorsAlpha);
  3287. needUpdateTexture = false;
  3288. }
  3289. void UpdateTextureColors (Color[] colors, bool forceUpdateEntireTexture) {
  3290. Vector3 nlight;
  3291. int nz, disp;
  3292. float nyspec;
  3293. float spec = 1.0001f - _specularThreshold;
  3294. int tw = adjustedTexture.width;
  3295. nlight = new Vector3 (-_lightDirection.x, 0, -_lightDirection.z).normalized * 0.3f;
  3296. nlight.y = _lightDirection.y > 0 ? Mathf.Clamp01 (1.0f - _lightDirection.y) : 1.0f - Mathf.Clamp01 (-_lightDirection.y);
  3297. nz = Mathf.FloorToInt (nlight.z * tw) * tw;
  3298. disp = (int)(nz + nlight.x * tw) + colors.Length;
  3299. nyspec = nlight.y / spec;
  3300. Color specularColor = currentFogSpecularColor * (1.0f + _specularIntensity) * _specularIntensity;
  3301. bool hasChanged = false;
  3302. if (updatingTextureSlice >= 1 || forceUpdateEntireTexture)
  3303. hasChanged = true;
  3304. float lcr = updatingTextureLightColor.r * 0.5f;
  3305. float lcg = updatingTextureLightColor.g * 0.5f;
  3306. float lcb = updatingTextureLightColor.b * 0.5f;
  3307. float scr = specularColor.r * 0.5f;
  3308. float scg = specularColor.g * 0.5f;
  3309. float scb = specularColor.b * 0.5f;
  3310. int count = colors.Length;
  3311. int k0 = 0;
  3312. int k1 = count;
  3313. if (updatingTextureSlice >= 0) {
  3314. if (updatingTextureSlice > _updateTextureSpread) {
  3315. // detected change of configuration amid texture updates
  3316. updatingTextureSlice = -1;
  3317. needUpdateTexture = true;
  3318. return;
  3319. }
  3320. k0 = count * updatingTextureSlice / _updateTextureSpread;
  3321. k1 = count * (updatingTextureSlice + 1) / _updateTextureSpread;
  3322. }
  3323. int z = 0;
  3324. for (int k = k0; k < k1; k++) {
  3325. int indexg = (k + disp) % count;
  3326. float a = colors [k].a;
  3327. float r = (a - colors [indexg].a) * nyspec;
  3328. if (r < 0f)
  3329. r = 0f;
  3330. else if (r > 1f)
  3331. r = 1f;
  3332. float cor = lcr + scr * r;
  3333. float cog = lcg + scg * r;
  3334. float cob = lcb + scb * r;
  3335. if (!hasChanged) {
  3336. if (z++ < 100) {
  3337. if (cor != colors [k].r || cog != colors [k].g || cob != colors [k].b) {
  3338. hasChanged = true;
  3339. }
  3340. } else if (!hasChanged) {
  3341. break;
  3342. }
  3343. }
  3344. colors [k].r = cor;
  3345. colors [k].g = cog;
  3346. colors [k].b = cob;
  3347. }
  3348. bool hasNewTextureData = forceUpdateEntireTexture;
  3349. if (hasChanged) {
  3350. if (updatingTextureSlice >= 0) {
  3351. updatingTextureSlice++;
  3352. if (updatingTextureSlice >= _updateTextureSpread) {
  3353. updatingTextureSlice = -1;
  3354. hasNewTextureData = true;
  3355. }
  3356. } else {
  3357. hasNewTextureData = true;
  3358. }
  3359. } else {
  3360. updatingTextureSlice = -1;
  3361. }
  3362. if (hasNewTextureData) {
  3363. if (Application.isPlaying && _turbulenceStrength > 0f && adjustedChaosTexture) {
  3364. adjustedChaosTexture.SetPixels (adjustedColors);
  3365. adjustedChaosTexture.Apply ();
  3366. } else {
  3367. adjustedTexture.SetPixels (adjustedColors);
  3368. adjustedTexture.Apply ();
  3369. fogMat.SetTexture ("_NoiseTex", adjustedTexture);
  3370. }
  3371. lastTextureUpdate = Time.time;
  3372. }
  3373. }
  3374. void ApplyChaos () {
  3375. if (!adjustedTexture)
  3376. return;
  3377. if (chaosLerpMat == null) {
  3378. Shader chaosLerp = Shader.Find ("VolumetricFogAndMist/Chaos Lerp");
  3379. chaosLerpMat = new Material (chaosLerp);
  3380. chaosLerpMat.hideFlags = HideFlags.DontSave;
  3381. }
  3382. turbAcum += deltaTime * _turbulenceStrength;
  3383. chaosLerpMat.SetFloat ("_Amount", turbAcum);
  3384. if (!adjustedChaosTexture) {
  3385. adjustedChaosTexture = Instantiate (adjustedTexture) as Texture2D;
  3386. adjustedChaosTexture.hideFlags = HideFlags.DontSave;
  3387. }
  3388. RenderTexture rtAdjusted = RenderTexture.GetTemporary (adjustedTexture.width, adjustedTexture.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
  3389. rtAdjusted.wrapMode = TextureWrapMode.Repeat;
  3390. Graphics.Blit (adjustedChaosTexture, rtAdjusted, chaosLerpMat);
  3391. fogMat.SetTexture ("_NoiseTex", rtAdjusted);
  3392. RenderTexture.ReleaseTemporary (rtAdjusted);
  3393. }
  3394. #endregion
  3395. #region Fog Volume
  3396. void CopyTransitionValues () {
  3397. currentFogAlpha = _alpha;
  3398. currentSkyHazeAlpha = _skyAlpha;
  3399. currentFogColor = _color;
  3400. currentFogSpecularColor = _specularColor;
  3401. currentLightColor = _lightColor;
  3402. }
  3403. public void SetTargetProfile (VolumetricFogProfile targetProfile, float duration) {
  3404. if (!_useFogVolumes)
  3405. return;
  3406. this.initialProfile = ScriptableObject.CreateInstance<VolumetricFogProfile> ();
  3407. this.initialProfile.Save (this);
  3408. this.targetProfile = targetProfile;
  3409. this.transitionDuration = duration;
  3410. this.transitionStartTime = Time.time;
  3411. this.transitionProfile = true;
  3412. }
  3413. public void ClearTargetProfile (float duration) {
  3414. SetTargetProfile (initialProfile, duration);
  3415. }
  3416. public void SetTargetAlpha (float newFogAlpha, float newSkyHazeAlpha, float duration) {
  3417. if (!_useFogVolumes)
  3418. return;
  3419. this.initialFogAlpha = currentFogAlpha;
  3420. this.initialSkyHazeAlpha = currentSkyHazeAlpha;
  3421. this.targetFogAlpha = newFogAlpha;
  3422. this.targetSkyHazeAlpha = newSkyHazeAlpha;
  3423. this.transitionDuration = duration;
  3424. this.transitionStartTime = Time.time;
  3425. this.transitionAlpha = true;
  3426. }
  3427. public void ClearTargetAlpha (float duration) {
  3428. SetTargetAlpha (-1, -1, duration);
  3429. }
  3430. public void SetTargetColor (Color newColor, float duration) {
  3431. if (!useFogVolumes)
  3432. return;
  3433. this.initialFogColor = currentFogColor;
  3434. this.targetFogColor = newColor;
  3435. this.transitionDuration = duration;
  3436. this.transitionStartTime = Time.time;
  3437. this.transitionColor = true;
  3438. this.targetColorActive = true;
  3439. }
  3440. public void ClearTargetColor (float duration) {
  3441. SetTargetColor (_color, duration);
  3442. this.targetColorActive = false;
  3443. }
  3444. public void SetTargetSpecularColor (Color newSpecularColor, float duration) {
  3445. if (!useFogVolumes)
  3446. return;
  3447. this.initialFogSpecularColor = currentFogSpecularColor;
  3448. this.targetFogSpecularColor = newSpecularColor;
  3449. this.transitionDuration = duration;
  3450. this.transitionStartTime = Time.time;
  3451. this.transitionSpecularColor = true;
  3452. this.targetSpecularColorActive = true;
  3453. }
  3454. public void ClearTargetSpecularColor (float duration) {
  3455. SetTargetSpecularColor (_specularColor, duration);
  3456. this.targetSpecularColorActive = false;
  3457. }
  3458. public void SetTargetLightColor (Color newLightColor, float duration) {
  3459. if (!useFogVolumes)
  3460. return;
  3461. this._sunCopyColor = false;
  3462. this.initialLightColor = currentLightColor;
  3463. this.targetLightColor = newLightColor;
  3464. this.transitionDuration = duration;
  3465. this.transitionStartTime = Time.time;
  3466. this.transitionLightColor = true;
  3467. this.targetLightColorActive = true;
  3468. }
  3469. public void ClearTargetLightColor (float duration) {
  3470. SetTargetLightColor (_lightColor, duration);
  3471. this.targetLightColorActive = false;
  3472. }
  3473. #endregion
  3474. #region Point Light functions
  3475. static string[] pointLightPositionUniformNames = new string[] {
  3476. "_FogPointLightPosition0",
  3477. "_FogPointLightPosition1",
  3478. "_FogPointLightPosition2",
  3479. "_FogPointLightPosition3",
  3480. "_FogPointLightPosition4",
  3481. "_FogPointLightPosition5"
  3482. };
  3483. static string[] pointLightColorUniformNames = new string[] {
  3484. "_FogPointLightColor0",
  3485. "_FogPointLightColor1",
  3486. "_FogPointLightColor2",
  3487. "_FogPointLightColor3",
  3488. "_FogPointLightColor4",
  3489. "_FogPointLightColor5"
  3490. };
  3491. void SetMaterialLightData (int k, Light lightComponent) {
  3492. Vector3 pos = _pointLightPositions [k];
  3493. pos.y -= _baselineHeight;
  3494. float range = _pointLightRanges [k] * _pointLightInscattering / 25f; // note: 25 comes from Unity point light attenuation equation
  3495. float multiplier = _pointLightIntensity * _pointLightIntensities [k] * _pointLightIntensitiesMultiplier [k];
  3496. Vector4 color = new Vector4 (_pointLightColors [k].r * multiplier, _pointLightColors [k].g * multiplier, _pointLightColors [k].b * multiplier, range);
  3497. fogMat.SetVector (pointLightPositionUniformNames [k], pos);
  3498. fogMat.SetVector (pointLightColorUniformNames [k], color);
  3499. }
  3500. public GameObject GetPointLight (int index) {
  3501. if (index < 0 || index > _pointLights.Length)
  3502. return null;
  3503. return _pointLights [index];
  3504. }
  3505. public void SetPointLight (int index, GameObject pointLight) {
  3506. if (index < 0 || index > _pointLights.Length)
  3507. return;
  3508. if (_pointLights [index] != pointLight) {
  3509. _pointLights [index] = pointLight;
  3510. UpdatePointLights ();
  3511. UpdateMaterialProperties ();
  3512. isDirty = true;
  3513. }
  3514. }
  3515. public float GetPointLightRange (int index) {
  3516. if (index < 0 || index > _pointLightRanges.Length)
  3517. return 0;
  3518. return _pointLightRanges [index];
  3519. }
  3520. public void SetPointLightRange (int index, float range) {
  3521. if (index < 0 || index > _pointLightRanges.Length)
  3522. return;
  3523. if (range != _pointLightRanges [index]) {
  3524. _pointLightRanges [index] = range;
  3525. UpdateMaterialProperties ();
  3526. isDirty = true;
  3527. }
  3528. }
  3529. public float GetPointLightIntensity (int index) {
  3530. if (index < 0 || index > _pointLightIntensities.Length)
  3531. return 0;
  3532. return _pointLightIntensities [index];
  3533. }
  3534. public void SetPointLightIntensity (int index, float intensity) {
  3535. if (index < 0 || index > _pointLightIntensities.Length)
  3536. return;
  3537. if (intensity != _pointLightIntensities [index]) {
  3538. _pointLightIntensities [index] = intensity;
  3539. UpdateMaterialProperties ();
  3540. isDirty = true;
  3541. }
  3542. }
  3543. public float GetPointLightIntensityMultiplier (int index) {
  3544. if (index < 0 || index > _pointLightIntensitiesMultiplier.Length)
  3545. return 0;
  3546. return _pointLightIntensitiesMultiplier [index];
  3547. }
  3548. public void SetPointLightIntensityMultiplier (int index, float intensityMultiplier) {
  3549. if (index < 0 || index > _pointLightIntensitiesMultiplier.Length)
  3550. return;
  3551. if (intensityMultiplier != _pointLightIntensitiesMultiplier [index]) {
  3552. _pointLightIntensitiesMultiplier [index] = intensityMultiplier;
  3553. UpdateMaterialProperties ();
  3554. isDirty = true;
  3555. }
  3556. }
  3557. public Vector3 GetPointLightPosition (int index) {
  3558. if (index < 0 || index > _pointLightPositions.Length)
  3559. return Vector3.zero;
  3560. return _pointLightPositions [index];
  3561. }
  3562. public void SetPointLightPosition (int index, Vector3 position) {
  3563. if (index < 0 || index > _pointLightPositions.Length)
  3564. return;
  3565. if (position != _pointLightPositions [index]) {
  3566. _pointLightPositions [index] = position;
  3567. UpdateMaterialProperties ();
  3568. isDirty = true;
  3569. }
  3570. }
  3571. public Color GetPointLightColor (int index) {
  3572. if (index < 0 || index > _pointLightColors.Length)
  3573. return Color.white;
  3574. return _pointLightColors [index];
  3575. }
  3576. public void SetPointLightColor (int index, Color color) {
  3577. if (index < 0 || index > _pointLightColors.Length)
  3578. return;
  3579. if (color != _pointLightColors [index]) {
  3580. _pointLightColors [index] = color;
  3581. UpdateMaterialProperties ();
  3582. isDirty = true;
  3583. }
  3584. }
  3585. // Look for new lights
  3586. void TrackNewLights () {
  3587. lastFoundLights = GameObject.FindObjectsOfType<Light> ();
  3588. }
  3589. // Look for nearest point lights
  3590. void TrackPointLights () {
  3591. if (!_pointLightTrackingAuto)
  3592. return;
  3593. if (_pointLightTrackingPivot == null) {
  3594. _pointLightTrackingPivot = transform;
  3595. }
  3596. // Look for new lights?
  3597. if (lastFoundLights == null || !Application.isPlaying || Time.time - trackPointCheckNewLightsLastTime > 3f) {
  3598. trackPointCheckNewLightsLastTime = Time.time;
  3599. TrackNewLights ();
  3600. }
  3601. // Sort nearest lights
  3602. int lightsFoundCount = lastFoundLights.Length;
  3603. if (lightBuffer == null || lightBuffer.Length != lightsFoundCount) {
  3604. lightBuffer = new Light[lightsFoundCount];
  3605. }
  3606. for (int k = 0; k < lightsFoundCount; k++) {
  3607. lightBuffer [k] = lastFoundLights [k];
  3608. }
  3609. bool changes = false;
  3610. for (int k = 0; k < MAX_POINT_LIGHTS; k++) {
  3611. GameObject g = null;
  3612. if (k < _pointLightTrackingCount) {
  3613. g = GetNearestLight (lightBuffer);
  3614. }
  3615. _pointLights [k] = g;
  3616. if (_pointLightRanges [k] != 0 && g == null) {
  3617. _pointLightRanges [k] = 0; // disables the light in case g is null
  3618. }
  3619. if (currentLights [k] != g) {
  3620. currentLights [k] = g;
  3621. changes = true;
  3622. }
  3623. }
  3624. // Update if there's any change
  3625. if (changes) {
  3626. UpdatePointLights ();
  3627. UpdateMaterialProperties ();
  3628. }
  3629. }
  3630. GameObject GetNearestLight (Light[] lights) {
  3631. float minDist = float.MaxValue;
  3632. Vector3 camPos = _pointLightTrackingPivot.position;
  3633. GameObject nearest = null;
  3634. int selected = -1;
  3635. for (int k = 0; k < lights.Length; k++) {
  3636. Light light = lights [k];
  3637. if (light == null || !light.enabled || light.type != LightType.Point)
  3638. continue;
  3639. GameObject g = lights [k].gameObject;
  3640. if (!g.activeSelf)
  3641. continue;
  3642. float dist = (g.transform.position - camPos).sqrMagnitude;
  3643. if (dist < minDist) {
  3644. nearest = g;
  3645. minDist = dist;
  3646. selected = k;
  3647. }
  3648. }
  3649. if (selected >= 0)
  3650. lights [selected] = null;
  3651. return nearest;
  3652. }
  3653. #endregion
  3654. #region Fog Area API
  3655. public static VolumetricFog CreateFogArea (Vector3 position, float radius, float height = 16, float fallOff = 1f) {
  3656. VolumetricFog fog = CreateFogAreaPlaceholder (true, position, radius, height, radius);
  3657. fog.preset = FOG_PRESET.SeaClouds;
  3658. fog.transform.position = position;
  3659. fog.skyHaze = 0;
  3660. fog.dithering = true;
  3661. return fog;
  3662. }
  3663. public static VolumetricFog CreateFogArea (Vector3 position, Vector3 boxSize) {
  3664. VolumetricFog fog = CreateFogAreaPlaceholder (false, position, boxSize.x * 0.5f, boxSize.y * 0.5f, boxSize.z * 0.5f);
  3665. fog.preset = FOG_PRESET.SeaClouds;
  3666. fog.transform.position = position;
  3667. fog.height = boxSize.y * 0.98f;
  3668. fog.skyHaze = 0;
  3669. return fog;
  3670. }
  3671. static VolumetricFog CreateFogAreaPlaceholder (bool spherical, Vector3 position, float radius, float height, float depth) {
  3672. GameObject prefab = spherical ? Resources.Load<GameObject> ("Prefabs/FogSphereArea") : Resources.Load<GameObject> ("Prefabs/FogBoxArea");
  3673. GameObject box = Instantiate (prefab) as GameObject;
  3674. box.transform.position = position;
  3675. box.transform.localScale = new Vector3 (radius, height, depth);
  3676. return box.GetComponent<VolumetricFog> ();
  3677. }
  3678. public static void RemoveAllFogAreas () {
  3679. VolumetricFog[] fogs = FindObjectsOfType<VolumetricFog> ();
  3680. for (int k = 0; k < fogs.Length; k++) {
  3681. if (fogs [k] != null && !fogs [k].hasCamera) {
  3682. DestroyImmediate (fogs [k].gameObject);
  3683. }
  3684. }
  3685. }
  3686. void CheckFogAreaDimensions () {
  3687. if (!_hasCamera && mr == null)
  3688. mr = GetComponent<MeshRenderer> ();
  3689. if (mr == null)
  3690. return;
  3691. Vector3 size = mr.bounds.extents;
  3692. switch (_fogAreaTopology) {
  3693. case FOG_AREA_TOPOLOGY.Box:
  3694. fogAreaRadius = size.x;
  3695. fogAreaHeight = size.y;
  3696. fogAreaDepth = size.z;
  3697. break;
  3698. case FOG_AREA_TOPOLOGY.Sphere:
  3699. fogAreaRadius = size.x;
  3700. if (transform.localScale.z != transform.localScale.x)
  3701. transform.localScale = new Vector3 (transform.localScale.x, transform.localScale.y, transform.localScale.x);
  3702. break;
  3703. }
  3704. if (_fogAreaCenter != null) {
  3705. if (_fogAreaFollowMode == FOG_AREA_FOLLOW_MODE.FullXYZ) {
  3706. transform.position = _fogAreaCenter.transform.position;
  3707. } else {
  3708. transform.position = new Vector3 (_fogAreaCenter.transform.position.x, transform.position.y, _fogAreaCenter.transform.position.z);
  3709. }
  3710. }
  3711. fogAreaPosition = transform.position;
  3712. }
  3713. #if UNITY_EDITOR
  3714. void OnDrawGizmos () {
  3715. if (_fogAreaRadius > 0 && _fogAreaShowGizmos) {
  3716. if (_fogAreaTopology == FOG_AREA_TOPOLOGY.Box) {
  3717. Gizmos.DrawWireCube (fogAreaPosition, new Vector3 (fogAreaRadius * 2f, fogAreaHeight * 2f, fogAreaDepth * 2f));
  3718. } else {
  3719. Gizmos.DrawWireSphere (fogAreaPosition, fogAreaRadius);
  3720. }
  3721. }
  3722. }
  3723. #endif
  3724. #endregion
  3725. }
  3726. }