1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
|
/*******************************************************************************
* photons.h
*
* This module contains all defines, typedefs, and prototypes for photons.cpp.
*
* Author: Nathan Kopp
*
* ---------------------------------------------------------------------------
* Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
* Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
*
* POV-Ray is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* POV-Ray is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ---------------------------------------------------------------------------
* POV-Ray is based on the popular DKB raytracer version 2.12.
* DKBTrace was originally written by David K. Buck.
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
* ---------------------------------------------------------------------------
* $File: //depot/public/povray/3.x/source/backend/lighting/photons.h $
* $Revision: #1 $
* $Change: 6069 $
* $DateTime: 2013/11/06 11:59:40 $
* $Author: chrisc $
*******************************************************************************/
#ifndef PHOTONS_H
#define PHOTONS_H
#include "base/povms.h"
#include "backend/frame.h"
#include "backend/render/trace.h"
#include "backend/control/messagefactory.h"
#include "backend/colour/colutils.h"
#include "backend/interior/media.h"
namespace pov
{
using namespace pov_base;
#define MEDIA_INTERACTION 1
/* ------------------------------------------------------ */
class ScenePhotonSettings
{
public:
ScenePhotonSettings()
{
photonsEnabled = false;
surfaceSeparation = 0.1;
globalSeparation = 0.1;
surfaceCount = 0;
expandTolerance = 0;
minExpandCount = 0;
minGatherCount = 10;
maxGatherCount = 100;
// trace settings for the photon pre-trace
Max_Trace_Level = 10;
adcBailout = 0.001;
jitter = 0.25;
// see the POV documentation for info about autostop
autoStopPercent = 1.0; // disabled by default
// these are used for saving or loading the photon map
// note: save and load are mutually exclusive - there are three states: save, load, neither
fileName = NULL;
saveFile = false;
loadFile = false;
#ifdef GLOBAL_PHOTONS
// ---------- global photon map ----------
int globalCount = 0; // disabled by default
#endif
// settings for media photons
mediaSpacingFactor = 0;
maxMediaSteps = 0; // disabled by default
// refleciton blur settings
// to be used with the reflection blur patch
//photonReflectionBlur = false;
}
~ScenePhotonSettings()
{
if ( fileName )
{
POV_FREE(fileName);
fileName=NULL;
}
}
bool photonsEnabled;
// photon separation (a.k.a. spacing)
DBL surfaceSeparation;
DBL globalSeparation;
// ...or photon count
int surfaceCount;
// settings for the adaptive search
// see POV documentation for an explanation
DBL expandTolerance;
int minExpandCount;
int minGatherCount;
int maxGatherCount;
// trace settings for the photon pre-trace
int Max_Trace_Level;
DBL adcBailout;
DBL jitter;
// see the POV documentation for info about autostop
DBL autoStopPercent;
// these are used for saving or loading the photon map
// note: save and load are mutually exclusive - there are three states: save, load, neither
char* fileName;
bool saveFile;
bool loadFile;
#ifdef GLOBAL_PHOTONS
// ---------- global photon map ----------
int globalPhotonsToShoot; // number of global photons to shoot
DBL globalGatherRad; // minimum gather radius
int globalCount;
#endif
// settings for media photons
DBL mediaSpacingFactor;
int maxMediaSteps;
// refleciton blur settings
// to be used with the reflection blur patch
//bool photonReflectionBlur;
};
/* ------------------------------------------------------ */
/* photon */
/* ------------------------------------------------------ */
struct Photon
{
void init(unsigned char _info)
{
this->info = _info;
}
SNGL_VECT Loc; /* location */
SMALL_COLOUR colour; /* color & intensity (flux) */
unsigned char info; /* info byte for kd-tree */
signed char theta, phi; /* incoming direction */
};
typedef Photon* PhotonBlock;
/* ------------------------------------------------------ */
/* photon map */
/* ------------------------------------------------------ */
/* this is for photon block allocation and array mapping functions */
extern const int PHOTON_BLOCK_POWER;
extern const int PHOTON_BLOCK_SIZE;
extern const int PHOTON_BLOCK_MASK;
extern const int INITIAL_BASE_ARRAY_SIZE;
class PhotonMap
{
public:
Photon **head;
int numBlocks; /* number of blocks in base array */
int numPhotons; /* total number of photons used */
DBL minGatherRad; /* minimum gather radius */
DBL minGatherRadMult; /* minimum gather radius multiplier (for speed adjustments) */
DBL gatherRadStep; /* step size for gather expansion */
int gatherNumSteps; /* maximum times to perform 'gather' */
PhotonMap();
~PhotonMap();
void swapPhotons(int a, int b);
void insertSort(int start, int end, int d);
void quickSortRec(int left, int right, int d);
void halfSortRec(int left, int right, int d, int mid);
void sortAndSubdivide(int start, int end, int /*sorted*/);
void buildTree();
void setGatherOptions(ScenePhotonSettings& photonSettings, int mediaMap);
Photon* AllocatePhoton();
//mutex allocatePhotonMutex;
void mergeMap(PhotonMap* map);
};
/* ------------------------------------------------------ */
/*
Photon array mapping function
This converts a one-dimensional index into a two-dimensional address
in the photon array.
Photon memory looks like this:
# -> **********
# -> ********** <- blocks of photons
# -> **********
# -> /
# -> /
:
^
|
Base array.
The base array (which is dynamically resized as needed) contians pointers
to blocks of photons. Blocks of photons (of fixed size of a power of two)
are allocated as needed.
This mapping function converts a one-dimensional index and into a two-
dimensional address consisting of a block index and an offset within
that block.
Note that, while this data structure allows easy allocation of photons,
it does not easily permit deallocation of photons. Once photons are placed
into the photon map, they are not removed.
*/
// if this is changed, you must also change swapPhotons() and
// allocatePhoton, both in photons.c
#define PHOTON_AMF(map, idx) map[(idx)>>PHOTON_BLOCK_POWER][(idx) & PHOTON_BLOCK_MASK]
/* ------------------------------------------------------ */
/* photon gatherer */
/* ------------------------------------------------------ */
class GatheredPhotons
{
public:
// priority queue arrays
Photon** photonGatherList; // photons
DBL *photonDistances; // priorities
int numFound; // number of photons found
void swapWith(GatheredPhotons& theOther);
GatheredPhotons(int maxGatherCount);
~GatheredPhotons();
};
class PhotonGatherer
{
public:
ScenePhotonSettings& photonSettings;
PhotonMap *map;
DBL size_sq_s; // search radius squared
DBL Size_s; // search radius (static)
DBL sqrt_dmax_s, dmax_s; // dynamic search radius... current maximum
int TargetNum_s; // how many to gather
const DBL *pt_s; // point around which we are gathering
const DBL *norm_s; // surface normal
DBL flattenFactor; // amount to flatten the spher to make it
// an ellipsoid when gathering photons
// zero = no flatten, one = regular
bool gathered;
DBL alreadyGatheredRadius;
GatheredPhotons gatheredPhotons;
PhotonGatherer(PhotonMap *map, ScenePhotonSettings& photonSettings);
void gatherPhotonsRec(int start, int end);
int gatherPhotons(const VECTOR pt, DBL Size, DBL *r, const VECTOR norm, bool flatten);
DBL gatherPhotonsAdaptive(const VECTOR pt, const VECTOR norm, bool flatten);
void PQInsert(Photon *photon, DBL d);
void FullPQInsert(Photon *photon, DBL d);
};
class PhotonMediaFunction : public MediaFunction
{
public:
PhotonMediaFunction(shared_ptr<SceneData> sd, TraceThreadData *td, Trace *t, PhotonGatherer *pg);
void ComputeMediaAndDepositPhotons(MediaVector& medias, const Ray& ray, const Intersection& isect, Colour& colour, Trace::TraceTicket& ticket);
protected:
void DepositMediaPhotons(Colour& colour, MediaVector& medias, LightSourceEntryVector& lights, MediaIntervalVector& mediaintervals,
const Ray& ray, int minsamples, bool ignore_photons, bool use_scattering, bool all_constant_and_light_ray, Trace::TraceTicket& ticket);
private:
shared_ptr<SceneData> sceneData;
void addMediaPhoton(const VECTOR Point, const VECTOR Origin, const RGBColour& LightCol, DBL depthDiff);
};
class PhotonTrace : public Trace
{
public:
PhotonTrace(shared_ptr<SceneData> sd, TraceThreadData *td, unsigned int mtl, DBL adcb, unsigned int qf, Trace::CooperateFunctor& cf);
~PhotonTrace();
virtual DBL TraceRay(const Ray& ray, Colour& colour, COLC weight, Trace::TraceTicket& ticket, bool continuedRay, DBL maxDepth = 0.0);
protected:
virtual void ComputeLightedTexture(Colour& LightCol, const TEXTURE *Texture, vector<const TEXTURE *>& warps, const Vector3d& ipoint, const Vector3d& rawnormal, const Ray& ray, COLC weight, Intersection& isect, Trace::TraceTicket& ticket);
bool ComputeRefractionForPhotons(const FINISH* finish, Interior *interior, const Vector3d& ipoint, const Ray& ray, const Vector3d& normal, const Vector3d& rawnormal, Colour& colour, COLC weight, Trace::TraceTicket& ticket);
bool TraceRefractionRayForPhotons(const FINISH* finish, const Vector3d& ipoint, const Ray& ray, Ray& nray, DBL ior, DBL n, const Vector3d& normal, const Vector3d& rawnormal, const Vector3d& localnormal, Colour& colour, COLC weight, Trace::TraceTicket& ticket);
private:
PhotonMediaFunction mediaPhotons;
RadiosityFunctor noRadiosity;
void addSurfacePhoton(const VECTOR Point, const VECTOR Origin, const RGBColour& LightCol);
};
// foward declaration
class PhotonShootingStrategy;
class LightTargetCombo;
/* ------------------------------------------------------ */
/* photon map builder */
/* ------------------------------------------------------ */
class ShootingDirection
{
public:
ShootingDirection(LightSource* light, ObjectPtr target):light(light),target(target) {}
LightSource* light;
ObjectPtr target;
VECTOR up, left, ctr, toctr, v; /* vectors to determine direction of shot */
DBL dist; /* distance from light to center of bounding sphere */
DBL rad; /* radius of bounding sphere */
void compute();
void recomputeForAreaLight(Ray& ray, int area_x, int area_y);
};
class LightTargetCombo
{
public:
LightTargetCombo(LightSource *light, ObjectPtr target):light(light),target(target),shootingDirection(light,target) {}
LightSource *light;
ObjectPtr target;
int estimate;
DBL mintheta;
DBL maxtheta;
DBL dtheta;
DBL photonSpread;
ShootingDirection shootingDirection;
int computeMergedFlags();
void computeAnglesAndDeltas(shared_ptr<SceneData> sceneData);
};
class PhotonShootingUnit
{
public:
PhotonShootingUnit(LightSource* light, ObjectPtr target):lightAndObject(light,target) {}
LightTargetCombo lightAndObject;
};
class SinCosOptimizations
{
public:
// speed optimization data - sin/cos stored in two arrays
// these are only created if photon mapping is used
// TODO move these to their own class
// these are thread safe - used many times but not modified after initialization
DBL *cosTheta;
DBL *sinTheta;
SinCosOptimizations();
~SinCosOptimizations();
};
extern SinCosOptimizations sinCosData;
/* ------------------------------------------------------ */
/* global functions */
/* for documentation of these functions, see photons.c */
/* ------------------------------------------------------ */
void ChooseRay(Ray &NewRay, const VECTOR Normal, const Ray &Ray, const VECTOR Raw_Normal, int WhichRay);
int GetPhotonStat(POVMSType a);
}
#endif
|