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
1.3.6