1 //------------------------------------------------------------------------------
3 //------------------------------------------------------------------------------
4 // SkyWorks : Copyright 2002 Mark J. Harris and
5 // The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its
8 // documentation for any purpose is hereby granted without fee, provided that
9 // the above copyright notice appear in all copies and that both that copyright
10 // notice and this permission notice appear in supporting documentation.
11 // Binaries may be compiled with this software without any royalties or
14 // The author(s) and The University of North Carolina at Chapel Hill make no
15 // representations about the suitability of this software for any purpose.
16 // It is provided "as is" without express or
21 * Interface definition for class SkyCloud.
23 #ifndef __SKYCLOUD_HPP__
24 #define __SKYCLOUD_HPP__
26 // warning for truncation of template name for browse info
27 #pragma warning( disable : 4786)
29 #include "SkyCloudParticle.hpp"
30 #include "SkyRenderable.hpp"
31 #include "SkyMinMaxBox.hpp"
33 #include "SkyArchive.hpp"
38 class SkyRenderableInstance;
41 //------------------------------------------------------------------------------
44 * @brief A renderable that represents a volumetric cloud.
46 * A SkyCloud is made up of particles, and is rendered using particle splatting.
47 * SkyCloud is intended to represent realisticly illuminated volumetric clouds
48 * through which the viewer and / or other objects can realistically pass.
50 * Realistic illumination is performed by the Illuminate() method, which uses a
51 * graphics hardware algorithm to precompute and store multiple forward scattering
52 * of light by each particle in the cloud. Clouds may be illuminated by multiple
53 * light sources. The light from each source is precomputed and stored at each
54 * particle. Each light's contribution is stored separately so that we can
55 * compute view-dependent (anisotropic) scattering at run-time. This gives realistic
56 * effects such as the "silver lining" that you see on a thick cloud when it crosses
57 * in front of the sun.
59 * At run-time, the cloud is rendered by drawing each particle as a view-oriented
60 * textured billboard (splat), with lighting computed from the precomputed illumination
61 * as follows: for each light source <i>l</i>, compute the scattering function (See _PhaseFunction())
62 * based on the view direction and the direction from the particle to the viewer. This
63 * scattering function modulates the lighting contribution of <i>l</i>. The modulated
64 * contributions are then added and used to modulate the color of the particle. The result
65 * is view-dependent scattering.
67 * If the phase (scattering) function is not enabled (see IsPhaseFunctionEnabled()), then the
68 * contributions of the light sources are simply added.
70 * @see SkyRenderableInstanceCloud, SkyCloudParticle, SkySceneManager
72 class SkyCloud : public SkyRenderable
78 virtual SKYRESULT Update(const Camera &cam, SkyRenderableInstance* pInstance = NULL);
80 virtual SKYRESULT Display(const Camera &camera, SkyRenderableInstance *pInstance = NULL);
82 SKYRESULT DisplaySplit(const Camera &camera,
83 const Vec3f &vecSplitPoint,
85 SkyRenderableInstance *pInstance = NULL);
87 SKYRESULT Illuminate( SkyLight *pLight,
88 SkyRenderableInstance* pInstance,
91 virtual SkyMinMaxBox* CopyBoundingVolume() const;
93 //! Enables the use of a scattering function for anisotropic light scattering.
94 void EnablePhaseFunction(bool bEnable) { _bUsePhaseFunction = bEnable; }
95 //! Returns true if the use of a scattering function is enabled.
96 bool IsPhaseFunctionEnabled() const { return _bUsePhaseFunction; }
98 SKYRESULT Save(SkyArchive &archive) const;
99 SKYRESULT Load(const SkyArchive &archive, float rScale = 1.0f, bool bLocal = false);
101 void Rotate(const Mat33f& rot);
102 void Translate(const Vec3f& trans);
103 void Scale(const float scale);
105 protected: // methods
108 SKY_CLOUD_SORT_TOWARD,
112 void _SortParticles( const Vec3f& vecViewDir,
113 const Vec3f& vecSortPoint,
116 void _CreateSplatTexture( unsigned int iResolution);
118 float _PhaseFunction(const Vec3f& vecLightDir, const Vec3f& vecViewDir);
120 protected: // datatypes
121 typedef std::vector<SkyCloudParticle*> ParticleArray;
122 typedef ParticleArray::iterator ParticleIterator;
123 typedef ParticleArray::const_iterator ParticleConstIterator;
125 typedef std::vector<Vec3f> DirectionArray;
126 typedef DirectionArray::iterator DirectionIterator;
128 class ParticleAwayComparator
131 bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
133 return ((*pA) < (*pB));
137 class ParticleTowardComparator
140 bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
142 return ((*pA) > (*pB));
147 ParticleArray _particles; // cloud particles
148 // particle sorting functors for STL sort.
149 ParticleTowardComparator _towardComparator;
150 ParticleAwayComparator _awayComparator;
152 DirectionArray _lightDirections; // light directions in cloud space (cached)
154 SkyMinMaxBox _boundingBox; // bounds
156 bool _bUsePhaseFunction;
158 Vec3f _vecLastSortViewDir;
159 Vec3f _vecLastSortCamPos;
162 float _rSplitDistance;
164 static SkyMaterial *s_pMaterial; // shared material for clouds.
165 static SkyMaterial *s_pShadeMaterial;// shared material for illumination pass.
166 static unsigned int s_iShadeResolution; // the resolution of the viewport used for shading
167 static float s_rAlbedo; // the cloud albedo
168 static float s_rExtinction; // the extinction of the clouds
169 static float s_rTransparency; // the transparency of the clouds
170 static float s_rScatterFactor; // How much the clouds scatter
171 static float s_rSortAngleErrorTolerance; // how far the view must turn to cause a resort.
172 static float s_rSortSquareDistanceTolerance; // how far the view must move to cause a resort.
175 #endif //__SKYCLOUD_HPP__