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"
40 class SkyRenderableInstance;
43 //------------------------------------------------------------------------------
46 * @brief A renderable that represents a volumetric cloud.
48 * A SkyCloud is made up of particles, and is rendered using particle splatting.
49 * SkyCloud is intended to represent realisticly illuminated volumetric clouds
50 * through which the viewer and / or other objects can realistically pass.
52 * Realistic illumination is performed by the Illuminate() method, which uses a
53 * graphics hardware algorithm to precompute and store multiple forward scattering
54 * of light by each particle in the cloud. Clouds may be illuminated by multiple
55 * light sources. The light from each source is precomputed and stored at each
56 * particle. Each light's contribution is stored separately so that we can
57 * compute view-dependent (anisotropic) scattering at run-time. This gives realistic
58 * effects such as the "silver lining" that you see on a thick cloud when it crosses
59 * in front of the sun.
61 * At run-time, the cloud is rendered by drawing each particle as a view-oriented
62 * textured billboard (splat), with lighting computed from the precomputed illumination
63 * as follows: for each light source <i>l</i>, compute the scattering function (See _PhaseFunction())
64 * based on the view direction and the direction from the particle to the viewer. This
65 * scattering function modulates the lighting contribution of <i>l</i>. The modulated
66 * contributions are then added and used to modulate the color of the particle. The result
67 * is view-dependent scattering.
69 * If the phase (scattering) function is not enabled (see IsPhaseFunctionEnabled()), then the
70 * contributions of the light sources are simply added.
72 * @see SkyRenderableInstanceCloud, SkyCloudParticle, SkySceneManager
74 class SkyCloud : public SkyRenderable
80 virtual SKYRESULT Update(const Camera &cam, SkyRenderableInstance* pInstance = NULL);
82 virtual SKYRESULT Display(const Camera &camera, SkyRenderableInstance *pInstance = NULL);
84 SKYRESULT DisplaySplit(const Camera &camera,
85 const Vec3f &vecSplitPoint,
87 SkyRenderableInstance *pInstance = NULL);
89 SKYRESULT Illuminate( SkyLight *pLight,
90 SkyRenderableInstance* pInstance,
93 virtual SkyMinMaxBox* CopyBoundingVolume() const;
95 //! Enables the use of a scattering function for anisotropic light scattering.
96 void EnablePhaseFunction(bool bEnable) { _bUsePhaseFunction = bEnable; }
97 //! Returns true if the use of a scattering function is enabled.
98 bool IsPhaseFunctionEnabled() const { return _bUsePhaseFunction; }
100 SKYRESULT Save(SkyArchive &archive) const;
101 SKYRESULT Load(const SkyArchive &archive, float rScale = 1.0f,double latitude=0.0, double longitude=0.0);
102 SKYRESULT Load(const unsigned char *data, unsigned int size, float rScale = 1.0f,double latitude=0.0,double longitude=0.0);
104 void Rotate(const Mat33f& rot);
105 void Translate(const Vec3f& trans);
106 void Scale(const float scale);
108 protected: // methods
111 SKY_CLOUD_SORT_TOWARD,
115 void _SortParticles( const Vec3f& vecViewDir,
116 const Vec3f& vecSortPoint,
119 void _CreateSplatTexture( unsigned int iResolution);
121 float _PhaseFunction(const Vec3f& vecLightDir, const Vec3f& vecViewDir);
123 protected: // datatypes
124 typedef std::vector<SkyCloudParticle*> ParticleArray;
125 typedef ParticleArray::iterator ParticleIterator;
126 typedef ParticleArray::const_iterator ParticleConstIterator;
128 typedef std::vector<Vec3f> DirectionArray;
129 typedef DirectionArray::iterator DirectionIterator;
131 class ParticleAwayComparator
134 bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
136 return ((*pA) < (*pB));
140 class ParticleTowardComparator
143 bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
145 return ((*pA) > (*pB));
150 ParticleArray _particles; // cloud particles
151 // particle sorting functors for STL sort.
152 ParticleTowardComparator _towardComparator;
153 ParticleAwayComparator _awayComparator;
155 DirectionArray _lightDirections; // light directions in cloud space (cached)
157 SkyMinMaxBox _boundingBox; // bounds
159 bool _bUsePhaseFunction;
161 Vec3f _vecLastSortViewDir;
162 Vec3f _vecLastSortCamPos;
165 float _rSplitDistance;
167 static SkyMaterial *s_pMaterial; // shared material for clouds.
168 static SkyMaterial *s_pShadeMaterial;// shared material for illumination pass.
169 static unsigned int s_iShadeResolution; // the resolution of the viewport used for shading
170 static float s_rAlbedo; // the cloud albedo
171 static float s_rExtinction; // the extinction of the clouds
172 static float s_rTransparency; // the transparency of the clouds
173 static float s_rScatterFactor; // How much the clouds scatter
174 static float s_rSortAngleErrorTolerance; // how far the view must turn to cause a resort.
175 static float s_rSortSquareDistanceTolerance; // how far the view must move to cause a resort.
178 #endif //__SKYCLOUD_HPP__