Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

photonmap.h

Go to the documentation of this file.
00001 /*
00002     toxic - A Global Illumination Renderer
00003     Copyright (C) 2003-2004 Francois Beaune
00004     Contact: http://toxicengine.sourceforge.net/
00005 
00006     This file is part of toxic.
00007 
00008     toxic is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     toxic is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with toxic; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 #ifndef TOXIC_RENDERER_PHOTONMAP_H
00024 #define TOXIC_RENDERER_PHOTONMAP_H
00025 
00026 #include "common/math/aabb3.h"
00027 #include "common/math/real.h"
00028 #include "common/math/vector3.h"
00029 #include "common/misc/progressmonitor.h"
00030 #include "common/misc/types.h"
00031 #include "color3.h"
00032 #include "globals.h"
00033 #include "photon.h"
00034 
00035 #include <cassert>
00036 #include <string>
00037 #include <vector>
00038 
00039 namespace toxic {
00040 
00041     class Context;
00042     class ShadingData;
00043     class SurfaceBasis;
00044 
00045     //! The photon map implementation is based on the reference implementation
00046     //! provided by Henrik Wann Jensen in his book "Realistic Image Synthesis
00047     //! Using Photon Mapping".
00048 
00049     class PhotonMap {
00050     public:
00051         PhotonMap();
00052         ~PhotonMap();
00053 
00054         //! Returns the size (in bytes) of the photon map in memory.
00055         int GetSizeInMemory() const;
00056 
00057         //! Creates and stores a photon into the photon map. 'direction' must
00058         //! be unit-length. Both 'position' and 'direction' must be expressed
00059         //! in world space. The power is expressed in W.
00060         void StorePhoton(
00061             const sheep::Point3 &position,
00062             const Color3 &power,
00063             const sheep::Vector3 &direction
00064 #ifdef ENABLE_RADIANCES_PRECOMPUTATION
00065             , const sheep::Vector3 &normal
00066 #endif  // ENABLE_RADIANCES_PRECOMPUTATION
00067             );
00068 
00069         //! This method is used to scale the power of all photons once they have
00070         //! been emitted from the light source.
00071         //! scale = 1 / (#emitted photons)
00072         //! Call this function after each light source is processed.
00073         void ScalePhotonPower(sheep::Real scale);
00074 
00075         //! Creates a left-balanced kd-tree from the flat array of photons.
00076         //! This function must be called prior to calling any of the ComputeRadiance(),
00077         //! ApproximateRadiance(), PrecomputeRadiances() and GetPrecomputedRadiance()
00078         //! methods.
00079         void Balance();
00080 
00081         //! Computes the radiance reflected toward a given direction due to the
00082         //! photon density on a given surface, around a given point. This is the
00083         //! slowest but the most accurate method to compute the reflected radiance
00084         //! in a given direction. The point, the surface normal and the outgoing
00085         //! direction are expressed in world space. The outgoing direction is such
00086         //! that it leaves the surface, and it is unit-length. The returned value
00087         //! is a radiance (W.m^-2.sr^-1).
00088         Color3 ComputeRadiance(
00089             const Context &context,
00090             const sheep::Point3 &point,
00091             const sheep::Vector3 &normal,
00092             const sheep::Vector3 &outgoing,
00093             const ShadingData &shadingdata,
00094             sheep::Real max_dist,
00095             int max_photons) const;
00096 
00097         //! Same as the ComputeRadiance() method, except that the surface is
00098         //! considered as a perfect lambertian surface. This method is faster
00099         //! than the ComputeRadiance() method, but it is also less accurate.
00100         //! The point and the surface normal are expressed in world space. The
00101         //! returned value is a radiance (W.m^-2.sr^-1).
00102         Color3 ApproximateRadiance(
00103             const sheep::Point3 &point,
00104             const sheep::Vector3 &normal,
00105             const ShadingData &shadingdata,
00106             sheep::Real max_dist,
00107             int max_photons) const;
00108 
00109 #ifdef ENABLE_RADIANCES_PRECOMPUTATION
00110 
00111         //! Precomputes the reflected radiance at photons location. This method
00112         //! calls the ApproximateRadiance() to compute the reflected radiance at
00113         //! a given photon's location, thus the surface carrying the photon is
00114         //! considered as a perfect lambertian surface. Be sure to call the
00115         //! Balance() method prior to calling this method, and be sure to call this
00116         //! method prior to the first call of the GetPrecomputedRadiance() method.
00117         void PrecomputeRadiances(
00118             int spacing,
00119             sheep::Real max_dist,
00120             int max_photons,
00121             sheep::ProgressMonitor *progmon = 0);
00122 
00123         //! Same as the ApproximateRadiance() method, but several times faster.
00124         //! The point and the surface normal are expressed in world space. The
00125         //! returned value is a radiance (W.m^-2.sr^-1). Be sure to call the
00126         //! PrecomputeRadiances() method prior to calling this method.
00127         Color3 GetPrecomputedRadiance(
00128             const sheep::Point3 &point,
00129             const sheep::Vector3 &normal,
00130             const ShadingData &shadingdata,
00131             sheep::Real max_dist) const;
00132 
00133 #endif  // ENABLE_RADIANCES_PRECOMPUTATION
00134 
00135         void BuildPhotonDirectionHistogram(
00136             const sheep::Point3 &position,
00137             const SurfaceBasis &surfacebasis,
00138             sheep::Real max_dist,
00139             int max_photons,
00140             sheep::Real *histogram,
00141             int m, int n,
00142             sheep::Real *total_power) const;
00143 
00144         //! Writes the photon map to disk. Returns true if writing was successful.
00145         bool WriteToFile(
00146             const std::string &filename,
00147             sheep::ProgressMonitor *progmon = 0) const;
00148 
00149         //! Creates a photon map by reading it from disk. Returns a pointer to the
00150         //! newly created photon map if successful, and 0 otherwise.
00151         static PhotonMap *CreateFromFile(
00152             const std::string &filename,
00153             sheep::ProgressMonitor *progmon = 0);
00154 
00155         int GetPhotonCount() const;
00156         const Photon &GetPhoton(int i) const;
00157 
00158     private:
00159         int m_stored_photons;
00160         int m_half_stored_photons;
00161         int m_prev_scale;
00162 
00163         //! The array of photons.
00164         std::vector<Photon> m_photons;
00165 
00166         //! Bounding box of the photon array.
00167         sheep::float32 m_bbox_min[3];
00168         sheep::float32 m_bbox_max[3];
00169 
00170         //! Some buffers used by the IrradianceEstimate() method.
00171         enum { BUF_SIZE = 10000 };
00172         sheep::float32 *m_dist2_buf;
00173         const Photon **m_index_buf;
00174 
00175         //! Signature string identifying photon map files.
00176         static const std::string m_photon_map_sig;
00177 
00178         //! median_split() splits the photon array into two separate pieces
00179         //! around the median, with all photons below the median in the
00180         //! lower half and all photons above the median in the upper half.
00181         //! The comparison criteria is the axis (indicated by the axis
00182         //! parameter). Inspired by routine in "Algorithms in C++" by
00183         //! Sedgewick.
00184         void median_split(
00185             Photon **p,
00186             int start, int end,
00187             int median,
00188             int axis) const;
00189 
00190         //! See "Realistic Image Synthesis Using Photon Mapping" chapter 6
00191         //! for an explanation of this function.
00192         void balance_segment(
00193             Photon **pbal,
00194             Photon **porg,
00195             int index,
00196             int start, int end);
00197 
00198         //! This structure is used only to locate the nearest photons.
00199         struct nearest_photons {
00200             int m_max;
00201             int m_found;
00202             int m_got_heap;
00203             sheep::float32 m_position[3];
00204             sheep::float32 *m_dist2;
00205             const Photon **m_index;
00206         };
00207 
00208         //! locate_photons() finds the nearest photons in the photon map
00209         //! given the parameters in np.
00210         void locate_photons(nearest_photons *np, int index) const;
00211 
00212 #ifdef ENABLE_RADIANCES_PRECOMPUTATION
00213 
00214         void locate_nearest_photon_with_irradiance(
00215             const sheep::Vector3 &normal,
00216             nearest_photons *np,
00217             int index) const;
00218 
00219 #endif  // ENABLE_RADIANCES_PRECOMPUTATION
00220     };
00221 
00222 #include "photonmap.inl"
00223 
00224 }
00225 
00226 #endif  // !TOXIC_RENDERER_PHOTONMAP_H

Generated on Tue May 11 01:31:51 2004 for toxic by doxygen 1.3.6