ATMOSPH.C 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399
  1. /****************************************************************************
  2. * atmosph.c
  3. *
  4. * This module contains all functions for atmospheric effects.
  5. *
  6. * from Persistence of Vision(tm) Ray Tracer
  7. * Copyright 1996,1999 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. * NOTICE: This source code file is provided so that users may experiment
  10. * with enhancements to POV-Ray and to port the software to platforms other
  11. * than those supported by the POV-Ray Team. There are strict rules under
  12. * which you are permitted to use this file. The rules are in the file
  13. * named POVLEGAL.DOC which should be distributed with this file.
  14. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  16. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23. #include "frame.h"
  24. #include "vector.h"
  25. #include "povproto.h"
  26. #include "atmosph.h"
  27. #include "chi2.h"
  28. #include "colour.h"
  29. #include "povray.h"
  30. #include "texture.h"
  31. #include "pigment.h"
  32. #include "objects.h"
  33. #include "lighting.h"
  34. #include "matrices.h"
  35. #include "media.h"
  36. #include "texture.h"
  37. #include "ray.h"
  38. /*****************************************************************************
  39. * Local preprocessor defines
  40. ******************************************************************************/
  41. #define BLACK_LEVEL 0.0001
  42. /*****************************************************************************
  43. * Local typedefs
  44. ******************************************************************************/
  45. /*****************************************************************************
  46. * Local variables
  47. ******************************************************************************/
  48. /*****************************************************************************
  49. * Static functions
  50. ******************************************************************************/
  51. static DBL constant_fog (RAY *Ray, DBL Depth, DBL Width, FOG *Fog, COLOUR Colour);
  52. static DBL ground_fog (RAY *Ray, DBL Depth, DBL Width, FOG *Fog, COLOUR Colour);
  53. static void do_fog (RAY *Ray, INTERSECTION *Intersection, COLOUR Colour, int Light_Ray_Flag);
  54. static void do_rainbow (RAY *Ray, INTERSECTION *Intersection, COLOUR Colour);
  55. static void do_skysphere (RAY *Ray, COLOUR Colour);
  56. /*****************************************************************************
  57. *
  58. * FUNCTION
  59. *
  60. * Initialize_Atmosphere_Code
  61. *
  62. * INPUT
  63. *
  64. * OUTPUT
  65. *
  66. * RETURNS
  67. *
  68. * AUTHOR
  69. *
  70. * Dieter Bayer
  71. *
  72. * DESCRIPTION
  73. *
  74. * Initialize atmosphere specific variables.
  75. *
  76. * CHANGES
  77. *
  78. * Aug 1995 : Creation.
  79. *
  80. ******************************************************************************/
  81. void Initialize_Atmosphere_Code()
  82. {
  83. }
  84. /*****************************************************************************
  85. *
  86. * FUNCTION
  87. *
  88. * Deinitialize_Atmosphere_Code
  89. *
  90. * INPUT
  91. *
  92. * OUTPUT
  93. *
  94. * RETURNS
  95. *
  96. * AUTHOR
  97. *
  98. * Dieter Bayer
  99. *
  100. * DESCRIPTION
  101. *
  102. * Deinitialize atmosphere specific variables.
  103. *
  104. * CHANGES
  105. *
  106. * Aug 1995 : Creation.
  107. *
  108. ******************************************************************************/
  109. void Deinitialize_Atmosphere_Code()
  110. {
  111. }
  112. /*****************************************************************************
  113. *
  114. * FUNCTION
  115. *
  116. * Do_Infinite_Atmosphere
  117. *
  118. * INPUT
  119. *
  120. * Ray - Current ray
  121. *
  122. * OUTPUT
  123. *
  124. * Colour - Color of the current ray
  125. *
  126. * RETURNS
  127. *
  128. * AUTHOR
  129. *
  130. * Dieter Bayer
  131. *
  132. * DESCRIPTION
  133. *
  134. * Apply atmospheric effects to an infinite ray.
  135. *
  136. * CHANGES
  137. *
  138. * Feb 1995 : Creation.
  139. *
  140. * Jun 1995 : Added code for alpha channel support. [DB]
  141. *
  142. ******************************************************************************/
  143. void Do_Infinite_Atmosphere(RAY *Ray, COLOUR Colour)
  144. {
  145. /* Set background color. */
  146. Assign_Colour(Colour, Frame.Background_Colour);
  147. Colour[FILTER] = 0.0;
  148. Colour[TRANSM] = 1.0;
  149. /* Determine atmospheric effects for infinite ray. */
  150. do_skysphere(Ray, Colour);
  151. }
  152. /*****************************************************************************
  153. *
  154. * FUNCTION
  155. *
  156. * Do_Finite_Atmosphere
  157. *
  158. * INPUT
  159. *
  160. * Ray - Current ray
  161. * Intersection - Current intersection
  162. * Light_Ray_Flag - TRUE if ray is a light source ray
  163. *
  164. * OUTPUT
  165. *
  166. * Colour - Color of the current ray
  167. *
  168. * RETURNS
  169. *
  170. * AUTHOR
  171. *
  172. * Dieter Bayer
  173. *
  174. * DESCRIPTION
  175. *
  176. * Apply atmospheric effects to a finite ray.
  177. *
  178. * CHANGES
  179. *
  180. * Feb 1995 : Creation.
  181. *
  182. ******************************************************************************/
  183. void Do_Finite_Atmosphere(RAY *Ray, INTERSECTION *Intersection, COLOUR Colour, int Light_Ray_Flag)
  184. {
  185. IMEDIA *Media_List[2];
  186. if (!Light_Ray_Flag)
  187. {
  188. do_rainbow(Ray, Intersection, Colour);
  189. }
  190. Media_List[0] = Frame.Atmosphere;
  191. Media_List[1] = NULL;
  192. Simulate_Media(Media_List, Ray, Intersection, Colour, Light_Ray_Flag);
  193. do_fog(Ray, Intersection, Colour, Light_Ray_Flag);
  194. }
  195. /*****************************************************************************
  196. *
  197. * FUNCTION
  198. *
  199. * do_fog
  200. *
  201. * INPUT
  202. *
  203. * Ray - current ray
  204. * Intersection - current intersection
  205. * Light_Ray_Flag - TRUE if ray is a light source ray
  206. *
  207. * OUTPUT
  208. *
  209. * Colour - color of current ray
  210. *
  211. * RETURNS
  212. *
  213. * AUTHOR
  214. *
  215. * POV-Ray Team
  216. *
  217. * DESCRIPTION
  218. *
  219. * Evaluate all fogs for the current ray and intersection.
  220. *
  221. * CHANGES
  222. *
  223. * Dec 1994 : Rewritten to allow multiple fogs. [DB]
  224. *
  225. * Apr 1995 : Added transmittance threshold and filtering. [DB]
  226. *
  227. * Jun 1995 : Added code for alpha channel support. [DB]
  228. *
  229. ******************************************************************************/
  230. static void do_fog(RAY *Ray, INTERSECTION *Intersection, COLOUR Colour, int Light_Ray_Flag)
  231. {
  232. DBL att, att_inv, width;
  233. COLOUR Col_Fog;
  234. COLOUR sum_att; /* total attenuation. */
  235. COLOUR sum_col; /* total color. */
  236. FOG *Fog;
  237. /* Why are we here. */
  238. if (Frame.Fog == NULL)
  239. {
  240. return;
  241. }
  242. /* Init total attenuation and total color. */
  243. Make_ColourA(sum_att, 1.0, 1.0, 1.0, 1.0, 1.0);
  244. Make_ColourA(sum_col, 0.0, 0.0, 0.0, 0.0, 0.0);
  245. /* Loop over all fogs. */
  246. for (Fog = Frame.Fog; Fog != NULL; Fog = Fog->Next)
  247. {
  248. /* Don't care about fogs with zero distance. */
  249. if (fabs(Fog->Distance) > EPSILON)
  250. {
  251. width = Intersection->Depth;
  252. switch (Fog->Type)
  253. {
  254. case GROUND_MIST:
  255. att = ground_fog(Ray, 0.0, width, Fog, Col_Fog);
  256. break;
  257. default:
  258. att = constant_fog(Ray, 0.0, width, Fog, Col_Fog);
  259. break;
  260. }
  261. /* Check for minimum transmittance. */
  262. if (att < Col_Fog[TRANSM])
  263. {
  264. att = Col_Fog[TRANSM];
  265. }
  266. /* Get attenuation sum due to filtered/unfiltered translucency. */
  267. sum_att[RED] *= att * ((1.0 - Col_Fog[FILTER]) + Col_Fog[FILTER] * Col_Fog[RED]);
  268. sum_att[GREEN] *= att * ((1.0 - Col_Fog[FILTER]) + Col_Fog[FILTER] * Col_Fog[GREEN]);
  269. sum_att[BLUE] *= att * ((1.0 - Col_Fog[FILTER]) + Col_Fog[FILTER] * Col_Fog[BLUE]);
  270. sum_att[FILTER] *= att * Col_Fog[FILTER];
  271. sum_att[TRANSM] *= att * Col_Fog[TRANSM];
  272. if (!Light_Ray_Flag)
  273. {
  274. att_inv = 1.0 - att;
  275. VAddScaledEq(sum_col, att_inv, Col_Fog);
  276. }
  277. }
  278. }
  279. /* Add light coming from background. */
  280. Colour[RED] = sum_col[RED] + sum_att[RED] * Colour[RED];
  281. Colour[GREEN] = sum_col[GREEN] + sum_att[GREEN] * Colour[GREEN];
  282. Colour[BLUE] = sum_col[BLUE] + sum_att[BLUE] * Colour[BLUE];
  283. Colour[FILTER] = sum_col[FILTER] + sum_att[FILTER] * Colour[FILTER];
  284. Colour[TRANSM] = sum_col[TRANSM] + sum_att[TRANSM] * Colour[TRANSM];
  285. }
  286. /*****************************************************************************
  287. *
  288. * FUNCTION
  289. *
  290. * do_rainbow
  291. *
  292. * INPUT
  293. *
  294. * Ray - Current ray
  295. * Intersection - Cuurent intersection
  296. *
  297. * OUTPUT
  298. *
  299. * Colour - Current colour
  300. *
  301. * RETURNS
  302. *
  303. * AUTHOR
  304. *
  305. * Dieter Bayer
  306. *
  307. * DESCRIPTION
  308. *
  309. * Create a rainbow using an impressionistic model.
  310. *
  311. * The model was taken from:
  312. *
  313. * Musgrave, F. Kenton, "Prisms and Rainbows: a Dispersion Model
  314. * for Computer Graphics", Proceedings of Graphics Interface '89 -
  315. * Vision Interface '89, p. 227-234.
  316. *
  317. * CHANGES
  318. *
  319. * Jul 1994 : Creation.
  320. *
  321. * Dec 1994 : Modified to allow multiple rainbows. [DB]
  322. *
  323. * Apr 1995 : Added rainbow arcs and filtering. [DB]
  324. *
  325. * Jun 1995 : Added code for alpha channel support. [DB]
  326. *
  327. ******************************************************************************/
  328. static void do_rainbow(RAY *Ray, INTERSECTION *Intersection, COLOUR Colour)
  329. {
  330. int n;
  331. DBL dot, k, ki, index, x, y, l, angle, fade, f;
  332. VECTOR Temp;
  333. COLOUR Cr, Ct;
  334. RAINBOW *Rainbow;
  335. /* Why are we here. */
  336. if (Frame.Rainbow == NULL)
  337. {
  338. return;
  339. }
  340. Make_ColourA(Ct, 0.0, 0.0, 0.0, 1.0, 1.0);
  341. n = 0;
  342. for (Rainbow = Frame.Rainbow; Rainbow != NULL; Rainbow = Rainbow->Next)
  343. {
  344. if ((Rainbow->Pigment != NULL) && (Rainbow->Distance != 0.0) && (Rainbow->Width != 0.0))
  345. {
  346. /* Get angle between ray direction and rainbow's up vector. */
  347. VDot(x, Ray->Direction, Rainbow->Right_Vector);
  348. VDot(y, Ray->Direction, Rainbow->Up_Vector);
  349. l = Sqr(x) + Sqr(y);
  350. if (l > 0.0)
  351. {
  352. l = sqrt(l);
  353. y /= l;
  354. }
  355. angle = fabs(acos(y));
  356. if (angle <= Rainbow->Arc_Angle)
  357. {
  358. /* Get dot product between ray direction and antisolar vector. */
  359. VDot(dot, Ray->Direction, Rainbow->Antisolar_Vector);
  360. if (dot >= 0.0)
  361. {
  362. /* Get index ([0;1]) into rainbow's colour map. */
  363. index = (acos(dot) - Rainbow->Angle) / Rainbow->Width;
  364. /* Jitter index. */
  365. if (Rainbow->Jitter > 0.0)
  366. {
  367. index += (2.0 * FRAND() - 1.0) * Rainbow->Jitter;
  368. }
  369. if ((index >= 0.0) && (index <= 1.0 - EPSILON))
  370. {
  371. /* Get colour from rainbow's colour map. */
  372. Make_Vector(Temp, index, 0.0, 0.0);
  373. Compute_Pigment(Cr, Rainbow->Pigment, Temp);
  374. /* Get fading value for falloff. */
  375. if ((Rainbow->Falloff_Width > 0.0) && (angle > Rainbow->Falloff_Angle))
  376. {
  377. fade = (angle - Rainbow->Falloff_Angle) / Rainbow->Falloff_Width;
  378. fade = (3.0 - 2.0 * fade) * fade * fade;
  379. }
  380. else
  381. {
  382. fade = 0.0;
  383. }
  384. /* Get attenuation factor due to distance. */
  385. k = exp(-Intersection->Depth / Rainbow->Distance);
  386. /* Colour's transm value is used as minimum attenuation value. */
  387. k = max(k, fade * (1.0 - Cr[TRANSM]) + Cr[TRANSM]);
  388. /* Now interpolate the colours. */
  389. ki = 1.0 - k;
  390. /* Attenuate filter value. */
  391. f = Cr[FILTER] * ki;
  392. Ct[RED] += k * Colour[RED] * ((1.0 - f) + f * Cr[RED]) + ki * Cr[RED];
  393. Ct[GREEN] += k * Colour[GREEN] * ((1.0 - f) + f * Cr[GREEN]) + ki * Cr[GREEN];
  394. Ct[BLUE] += k * Colour[BLUE] * ((1.0 - f) + f * Cr[BLUE]) + ki * Cr[BLUE];
  395. Ct[FILTER] *= k * Cr[FILTER];
  396. Ct[TRANSM] *= k * Cr[TRANSM];
  397. n++;
  398. }
  399. }
  400. }
  401. }
  402. }
  403. if (n > 0)
  404. {
  405. VInverseScale(Colour, Ct, (DBL)n);
  406. Colour[FILTER] *= Ct[FILTER];
  407. Colour[TRANSM] *= Ct[TRANSM];
  408. }
  409. }
  410. /*****************************************************************************
  411. *
  412. * FUNCTION
  413. *
  414. * do_skysphere
  415. *
  416. * INPUT
  417. *
  418. * Ray - Current ray
  419. *
  420. * OUTPUT
  421. *
  422. * Colour - Current color
  423. *
  424. * RETURNS
  425. *
  426. * AUTHOR
  427. *
  428. * Dieter Bayer
  429. *
  430. * DESCRIPTION
  431. *
  432. * Calculate color of the sky.
  433. *
  434. * Use the ray direction as a point on the skysphere. Thus the sky can
  435. * easily be colored with all kinds of pigments.
  436. *
  437. * CHANGES
  438. *
  439. * Jul 1994 : Creation.
  440. *
  441. * Dec 1994 : Modified to allow layered pigments. [DB]
  442. *
  443. * Jun 1995 : Added code for alpha channel support. [DB]
  444. *
  445. ******************************************************************************/
  446. static void do_skysphere(RAY *Ray, COLOUR Colour)
  447. {
  448. int i;
  449. DBL att, trans;
  450. COLOUR Col, Col_Temp, Filter;
  451. VECTOR P;
  452. SKYSPHERE *Skysphere;
  453. /* Why are we here. */
  454. if (Frame.Skysphere == NULL)
  455. {
  456. return;
  457. }
  458. Make_Colour(Col, 0.0, 0.0, 0.0);
  459. if (((Skysphere = Frame.Skysphere) != NULL) && (Skysphere->Pigments != NULL))
  460. {
  461. Make_ColourA(Filter, 1.0, 1.0, 1.0, 1.0, 1.0);
  462. trans = 1.0;
  463. /* Transform point on unit sphere. */
  464. if (Skysphere->Trans != NULL)
  465. {
  466. MInvTransPoint(P, Ray->Direction, Skysphere->Trans);
  467. }
  468. else
  469. {
  470. Assign_Vector(P, Ray->Direction);
  471. }
  472. for (i = Skysphere->Count-1; i >= 0; i--)
  473. {
  474. /* Compute sky colour from colour map. */
  475. Compute_Pigment(Col_Temp, Skysphere->Pigments[i], P);
  476. att = trans * (1.0 - Col_Temp[FILTER] - Col_Temp[TRANSM]);
  477. VAddScaledEq(Col, att, Col_Temp);
  478. Filter[RED] *= Col_Temp[RED];
  479. Filter[GREEN] *= Col_Temp[GREEN];
  480. Filter[BLUE] *= Col_Temp[BLUE];
  481. Filter[FILTER] *= Col_Temp[FILTER];
  482. Filter[TRANSM] *= Col_Temp[TRANSM];
  483. trans = fabs(Filter[FILTER]) + fabs(Filter[TRANSM]);
  484. }
  485. Colour[RED] = Col[RED] + Colour[RED] * (Filter[RED] * Filter[FILTER] + Filter[TRANSM]);
  486. Colour[GREEN] = Col[GREEN] + Colour[GREEN] * (Filter[GREEN] * Filter[FILTER] + Filter[TRANSM]);
  487. Colour[BLUE] = Col[BLUE] + Colour[BLUE] * (Filter[BLUE] * Filter[FILTER] + Filter[TRANSM]);
  488. Colour[FILTER] = Colour[FILTER] * Filter[FILTER];
  489. Colour[TRANSM] = Colour[TRANSM] * Filter[TRANSM];
  490. }
  491. }
  492. /*****************************************************************************
  493. *
  494. * FUNCTION
  495. *
  496. * constant_fog
  497. *
  498. * INPUT
  499. *
  500. * Ray - current ray
  501. * Depth - intersection depth with fog's boundary
  502. * Width - width of the fog along the ray
  503. * Fog - current fog
  504. *
  505. * OUTPUT
  506. *
  507. * Colour - color of the fog
  508. *
  509. * RETURNS
  510. *
  511. * AUTHOR
  512. *
  513. * POV-Ray Team
  514. *
  515. * DESCRIPTION
  516. *
  517. * Apply distance attenuated fog.
  518. *
  519. * CHANGES
  520. *
  521. * Dec 1994 : Modified to work with multiple fogs. [DB]
  522. *
  523. ******************************************************************************/
  524. static DBL constant_fog(RAY *Ray, DBL Depth, DBL Width, FOG *Fog, COLOUR Colour)
  525. {
  526. DBL k;
  527. VECTOR P;
  528. if (Fog->Turb != NULL)
  529. {
  530. Depth += Width / 2.0;
  531. VEvaluateRay(P, Ray->Initial, Depth, Ray->Direction);
  532. VEvaluateEq(P, Fog->Turb->Turbulence);
  533. /* The further away the less influence turbulence has. */
  534. k = exp(-Width / Fog->Distance);
  535. Width *= 1.0 - k * min(1.0, Turbulence(P, Fog->Turb)*Fog->Turb_Depth);
  536. }
  537. Assign_Colour(Colour, Fog->Colour);
  538. return (exp(-Width / Fog->Distance));
  539. }
  540. /*****************************************************************************
  541. *
  542. * FUNCTION
  543. *
  544. * ground_fog
  545. *
  546. * INPUT
  547. *
  548. * Ray - current ray
  549. * Depth - intersection depth with fog's boundary
  550. * Width - width of the fog along the ray
  551. * Fog - current fog
  552. *
  553. * OUTPUT
  554. *
  555. * Colour - color of the fog
  556. *
  557. * RETURNS
  558. *
  559. * AUTHOR
  560. *
  561. * Eric Barish
  562. *
  563. * DESCRIPTION
  564. *
  565. * Here is an ascii graph of the ground fog density, it has a maximum
  566. * density of 1.0 at Y <= 0, and approaches 0.0 as Y goes up:
  567. *
  568. * ***********************************
  569. * | | | ****
  570. * | | | ***
  571. * | | | ***
  572. * | | | | ****
  573. * | | | | *****
  574. * | | | | *******
  575. * -----+-----------+------------+------------+-----------+-----
  576. * Y=-2 Y=-1 Y=0 Y=1 Y=2
  577. *
  578. * ground fog density is 1 / (Y*Y+1) for Y >= 0 and equals 1.0 for Y <= 0.
  579. * (It behaves like regular fog for Y <= 0.)
  580. *
  581. * The integral of the density is atan(Y) (for Y >= 0).
  582. *
  583. * CHANGES
  584. *
  585. * Feb 1996 : Changed to behave like normal fog for Y <= 0.
  586. * Fixed bug with reversed offset effect. [DB]
  587. *
  588. ******************************************************************************/
  589. static DBL ground_fog(RAY *Ray, DBL Depth, DBL Width, FOG *Fog, COLOUR Colour)
  590. {
  591. DBL fog_density, delta;
  592. DBL start, end;
  593. DBL y1, y2, k;
  594. VECTOR P, P1, P2;
  595. /* Get start point. */
  596. VEvaluateRay(P1, Ray->Initial, Depth, Ray->Direction);
  597. /* Get end point. */
  598. VLinComb2(P2, 1.0, P1, Width, Ray->Direction);
  599. /*
  600. * Could preform transfomation here to translate Start and End
  601. * points into ground fog space.
  602. */
  603. VDot(y1, P1, Fog->Up);
  604. VDot(y2, P2, Fog->Up);
  605. start = (y1 - Fog->Offset) / Fog->Alt;
  606. end = (y2 - Fog->Offset) / Fog->Alt;
  607. /* Get integral along y-axis from start to end. */
  608. if (start <= 0.0)
  609. {
  610. if (end <= 0.0)
  611. {
  612. fog_density = 1.0;
  613. }
  614. else
  615. {
  616. fog_density = (atan(end) - start) / (end - start);
  617. }
  618. }
  619. else
  620. {
  621. if (end <= 0.0)
  622. {
  623. fog_density = (atan(start) - end) / (start - end);
  624. }
  625. else
  626. {
  627. delta = start - end;
  628. if (fabs(delta) > EPSILON)
  629. {
  630. fog_density = (atan(start) - atan(end)) / delta;
  631. }
  632. else
  633. {
  634. fog_density = 1.0 / (Sqr(start) + 1.0);
  635. }
  636. }
  637. }
  638. /* Apply turbulence. */
  639. if (Fog->Turb != NULL)
  640. {
  641. VHalf(P, P1, P2);
  642. VEvaluateEq(P, Fog->Turb->Turbulence);
  643. /* The further away the less influence turbulence has. */
  644. k = exp(-Width / Fog->Distance);
  645. Width *= 1.0 - k * min(1.0, Turbulence(P, Fog->Turb)*Fog->Turb_Depth);
  646. }
  647. Assign_Colour(Colour, Fog->Colour);
  648. return (exp(-Width * fog_density / Fog->Distance));
  649. }
  650. /*****************************************************************************
  651. *
  652. * FUNCTION
  653. *
  654. * Create_Fog
  655. *
  656. * INPUT
  657. *
  658. * OUTPUT
  659. *
  660. * RETURNS
  661. *
  662. * FOG * - created fog
  663. *
  664. * AUTHOR
  665. *
  666. * Dieter Bayer
  667. *
  668. * DESCRIPTION
  669. *
  670. * Create a fog.
  671. *
  672. * CHANGES
  673. *
  674. * Dec 1994 : Creation.
  675. *
  676. ******************************************************************************/
  677. FOG *Create_Fog()
  678. {
  679. FOG *New;
  680. New = (FOG *)POV_MALLOC(sizeof(FOG), "fog");
  681. New->Type = ORIG_FOG;
  682. New->Distance = 0.0;
  683. New->Alt = 0.0;
  684. New->Offset = 0.0;
  685. Make_ColourA(New->Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  686. Make_Vector(New->Up, 0.0, 1.0, 0.0);
  687. New->Turb = NULL;
  688. New->Turb_Depth = 0.5;
  689. New->Next = NULL;
  690. return (New);
  691. }
  692. /*****************************************************************************
  693. *
  694. * FUNCTION
  695. *
  696. * Copy_Fog
  697. *
  698. * INPUT
  699. *
  700. * Old - fog to copy
  701. *
  702. * OUTPUT
  703. *
  704. * RETURNS
  705. *
  706. * FOG * - new fog
  707. *
  708. * AUTHOR
  709. *
  710. * Dieter Bayer
  711. *
  712. * DESCRIPTION
  713. *
  714. * Copy a fog.
  715. *
  716. * CHANGES
  717. *
  718. * Dec 1994 : Creation.
  719. *
  720. ******************************************************************************/
  721. FOG *Copy_Fog(FOG *Old)
  722. {
  723. FOG *New;
  724. New = Create_Fog();
  725. *New = *Old;
  726. New->Turb = (TURB *)Copy_Warps(((WARP *)Old->Turb));
  727. return (New);
  728. }
  729. /*****************************************************************************
  730. *
  731. * FUNCTION
  732. *
  733. * Destroy_Fog
  734. *
  735. * INPUT
  736. *
  737. * Fog - fog to destroy
  738. *
  739. * OUTPUT
  740. *
  741. * RETURNS
  742. *
  743. * AUTHOR
  744. *
  745. * Dieter Bayer
  746. *
  747. * DESCRIPTION
  748. *
  749. * Destroy a fog.
  750. *
  751. * CHANGES
  752. *
  753. * Dec 1994 : Creation.
  754. *
  755. ******************************************************************************/
  756. void Destroy_Fog(FOG *Fog)
  757. {
  758. if (Fog != NULL)
  759. {
  760. Destroy_Turb(Fog->Turb);
  761. POV_FREE(Fog);
  762. }
  763. }
  764. /*****************************************************************************
  765. *
  766. * FUNCTION
  767. *
  768. * Create_Rainbow
  769. *
  770. * INPUT
  771. *
  772. * OUTPUT
  773. *
  774. * RETURNS
  775. *
  776. * RAINBOW * - created rainbow
  777. *
  778. * AUTHOR
  779. *
  780. * Dieter Bayer
  781. *
  782. * DESCRIPTION
  783. *
  784. * Create a rainbow.
  785. *
  786. * CHANGES
  787. *
  788. * Dec 1994 : Creation.
  789. *
  790. ******************************************************************************/
  791. RAINBOW *Create_Rainbow()
  792. {
  793. RAINBOW *New;
  794. New = (RAINBOW *)POV_MALLOC(sizeof(RAINBOW), "fog");
  795. New->Distance = Max_Distance;
  796. New->Jitter = 0.0;
  797. New->Angle = 0.0;
  798. New->Width = 0.0;
  799. New->Falloff_Width = 0.0;
  800. New->Arc_Angle = 180.0;
  801. New->Falloff_Angle = 180.0;
  802. New->Pigment = NULL;
  803. Make_Vector(New->Antisolar_Vector, 0.0, 0.0, 0.0);
  804. Make_Vector(New->Right_Vector, 1.0, 0.0, 0.0);
  805. Make_Vector(New->Up_Vector, 0.0, 1.0, 0.0);
  806. New->Next = NULL;
  807. return (New);
  808. }
  809. /*****************************************************************************
  810. *
  811. * FUNCTION
  812. *
  813. * Copy_Rainbow
  814. *
  815. * INPUT
  816. *
  817. * Old - rainbow to copy
  818. *
  819. * OUTPUT
  820. *
  821. * RETURNS
  822. *
  823. * RAINBOW * - new rainbow
  824. *
  825. * AUTHOR
  826. *
  827. * Dieter Bayer
  828. *
  829. * DESCRIPTION
  830. *
  831. * Copy a rainbow.
  832. *
  833. * CHANGES
  834. *
  835. * Dec 1994 : Creation.
  836. *
  837. ******************************************************************************/
  838. RAINBOW *Copy_Rainbow(RAINBOW *Old)
  839. {
  840. RAINBOW *New;
  841. New = Create_Rainbow();
  842. *New = *Old;
  843. return (New);
  844. }
  845. /*****************************************************************************
  846. *
  847. * FUNCTION
  848. *
  849. * Destroy_Rainbow
  850. *
  851. * INPUT
  852. *
  853. * Rainbow - rainbow to destroy
  854. *
  855. * OUTPUT
  856. *
  857. * RETURNS
  858. *
  859. * AUTHOR
  860. *
  861. * Dieter Bayer
  862. *
  863. * DESCRIPTION
  864. *
  865. * Destroy a rainbow.
  866. *
  867. * CHANGES
  868. *
  869. * Dec 1994 : Creation.
  870. *
  871. ******************************************************************************/
  872. void Destroy_Rainbow(RAINBOW *Rainbow)
  873. {
  874. if (Rainbow != NULL)
  875. {
  876. Destroy_Pigment(Rainbow->Pigment);
  877. POV_FREE(Rainbow);
  878. }
  879. }
  880. /*****************************************************************************
  881. *
  882. * FUNCTION
  883. *
  884. * Create_Skysphere
  885. *
  886. * INPUT
  887. *
  888. * OUTPUT
  889. *
  890. * RETURNS
  891. *
  892. * SKYSPHERE * - created skysphere
  893. *
  894. * AUTHOR
  895. *
  896. * Dieter Bayer
  897. *
  898. * DESCRIPTION
  899. *
  900. * Create a skysphere.
  901. *
  902. * CHANGES
  903. *
  904. * Dec 1994 : Creation.
  905. *
  906. ******************************************************************************/
  907. SKYSPHERE *Create_Skysphere()
  908. {
  909. SKYSPHERE *New;
  910. New = (SKYSPHERE *)POV_MALLOC(sizeof(SKYSPHERE), "fog");
  911. New->Count = 0;
  912. New->Pigments = NULL;
  913. New->Trans = Create_Transform();
  914. return (New);
  915. }
  916. /*****************************************************************************
  917. *
  918. * FUNCTION
  919. *
  920. * Copy_Skysphere
  921. *
  922. * INPUT
  923. *
  924. * Old - skysphere to copy
  925. *
  926. * OUTPUT
  927. *
  928. * RETURNS
  929. *
  930. * SKYSPHERE * - copied skysphere
  931. *
  932. * AUTHOR
  933. *
  934. * Dieter Bayer
  935. *
  936. * DESCRIPTION
  937. *
  938. * Copy a skysphere.
  939. *
  940. * CHANGES
  941. *
  942. * Dec 1994 : Creation.
  943. *
  944. ******************************************************************************/
  945. SKYSPHERE *Copy_Skysphere(SKYSPHERE *Old)
  946. {
  947. int i;
  948. SKYSPHERE *New;
  949. New = Create_Skysphere();
  950. Destroy_Transform(New->Trans);
  951. *New = *Old;
  952. New->Trans = Copy_Transform(Old->Trans);
  953. if (New->Count > 0)
  954. {
  955. New->Pigments = (PIGMENT **)POV_MALLOC(New->Count*sizeof(PIGMENT *), "skysphere pigment");
  956. for (i = 0; i < New->Count; i++)
  957. {
  958. New->Pigments[i] = Copy_Pigment(Old->Pigments[i]);
  959. }
  960. }
  961. return (New);
  962. }
  963. /*****************************************************************************
  964. *
  965. * FUNCTION
  966. *
  967. * Destroy_Skysphere
  968. *
  969. * INPUT
  970. *
  971. * Skysphere - skysphere to destroy
  972. *
  973. * OUTPUT
  974. *
  975. * RETURNS
  976. *
  977. * AUTHOR
  978. *
  979. * Dieter Bayer
  980. *
  981. * DESCRIPTION
  982. *
  983. * Destroy a skysphere.
  984. *
  985. * CHANGES
  986. *
  987. * Dec 1994 : Creation.
  988. *
  989. ******************************************************************************/
  990. void Destroy_Skysphere(SKYSPHERE *Skysphere)
  991. {
  992. int i;
  993. if (Skysphere != NULL)
  994. {
  995. for (i = 0; i < Skysphere->Count; i++)
  996. {
  997. Destroy_Pigment(Skysphere->Pigments[i]);
  998. }
  999. POV_FREE(Skysphere->Pigments);
  1000. Destroy_Transform(Skysphere->Trans);
  1001. POV_FREE(Skysphere);
  1002. }
  1003. }
  1004. /*****************************************************************************
  1005. *
  1006. * FUNCTION
  1007. *
  1008. * Rotate_Skysphere
  1009. *
  1010. * INPUT
  1011. *
  1012. * Vector - Rotation vector
  1013. *
  1014. * OUTPUT
  1015. *
  1016. * Skysphere - Pointer to skysphere structure
  1017. *
  1018. * RETURNS
  1019. *
  1020. * AUTHOR
  1021. *
  1022. * Dieter Bayer
  1023. *
  1024. * DESCRIPTION
  1025. *
  1026. * Rotate a skysphere.
  1027. *
  1028. * CHANGES
  1029. *
  1030. * Feb 1996 : Creation.
  1031. *
  1032. ******************************************************************************/
  1033. void Rotate_Skysphere(SKYSPHERE *Skysphere, VECTOR Vector)
  1034. {
  1035. TRANSFORM Trans;
  1036. Compute_Rotation_Transform(&Trans, Vector);
  1037. Transform_Skysphere(Skysphere, &Trans);
  1038. }
  1039. /*****************************************************************************
  1040. *
  1041. * FUNCTION
  1042. *
  1043. * Scale_Skysphere
  1044. *
  1045. * INPUT
  1046. *
  1047. * Vector - Scaling vector
  1048. *
  1049. * OUTPUT
  1050. *
  1051. * Skysphere - Pointer to skysphere structure
  1052. *
  1053. * RETURNS
  1054. *
  1055. * AUTHOR
  1056. *
  1057. * Dieter Bayer
  1058. *
  1059. * DESCRIPTION
  1060. *
  1061. * Scale a skysphere.
  1062. *
  1063. * CHANGES
  1064. *
  1065. * Feb 1996 : Creation.
  1066. *
  1067. ******************************************************************************/
  1068. void Scale_Skysphere(SKYSPHERE *Skysphere, VECTOR Vector)
  1069. {
  1070. TRANSFORM Trans;
  1071. Compute_Scaling_Transform(&Trans, Vector);
  1072. Transform_Skysphere(Skysphere, &Trans);
  1073. }
  1074. /*****************************************************************************
  1075. *
  1076. * FUNCTION
  1077. *
  1078. * Translate_Skysphere
  1079. *
  1080. * INPUT
  1081. *
  1082. * Vector - Translation vector
  1083. *
  1084. * OUTPUT
  1085. *
  1086. * Skysphere - Pointer to skysphere structure
  1087. *
  1088. * RETURNS
  1089. *
  1090. * AUTHOR
  1091. *
  1092. * Dieter Bayer
  1093. *
  1094. * DESCRIPTION
  1095. *
  1096. * Translate a skysphere.
  1097. *
  1098. * CHANGES
  1099. *
  1100. * Feb 1996 : Creation.
  1101. *
  1102. ******************************************************************************/
  1103. void Translate_Skysphere(SKYSPHERE *Skysphere, VECTOR Vector)
  1104. {
  1105. TRANSFORM Trans;
  1106. Compute_Translation_Transform(&Trans, Vector);
  1107. Transform_Skysphere(Skysphere, &Trans);
  1108. }
  1109. /*****************************************************************************
  1110. *
  1111. * FUNCTION
  1112. *
  1113. * Transform_Skysphere
  1114. *
  1115. * INPUT
  1116. *
  1117. * Trans - Pointer to transformation
  1118. *
  1119. * OUTPUT
  1120. *
  1121. * Skysphere - Pointer to skysphere structure
  1122. *
  1123. * RETURNS
  1124. *
  1125. * AUTHOR
  1126. *
  1127. * Dieter Bayer
  1128. *
  1129. * DESCRIPTION
  1130. *
  1131. * Transform a skysphere.
  1132. *
  1133. * CHANGES
  1134. *
  1135. * Feb 1996 : Creation.
  1136. *
  1137. ******************************************************************************/
  1138. void Transform_Skysphere(SKYSPHERE *Skysphere, TRANSFORM *Trans)
  1139. {
  1140. if (Skysphere->Trans == NULL)
  1141. {
  1142. Skysphere->Trans = Create_Transform();
  1143. }
  1144. Compose_Transforms(Skysphere->Trans, Trans);
  1145. }