diff --git a/README-photonflow.txt b/README-photonflow.txt index a86d1e6..699eeaa 100644 --- a/README-photonflow.txt +++ b/README-photonflow.txt @@ -1,191 +1,199 @@ This is the README file for the RADIANCE photon flow implementation. This software was developed as part of the project "Three-Dimensional Light Flow", hosted by Tokyo University of Science under the supervision of Prof. Nozomu Yoshizawa, and supported by the JSPS Grants-in-Aid for Scientific Research (KAKENHI) under the grant number JP19KK0115. $Revision: 1.3 $ $Date: 2020/11/16 22:41:09 $ INTRODUCTION These source files implement a modified volume photon density estimate in RADIANCE to evaluate the illuminance of a physical lightfield using photon flow. This code is an experimental variant of the RADIANCE photon map extension intended for testing prior to committing it to the RADIANCE CVS as part of the official distribution. Whether this (admittedly specialised) functionality should be made available to the RADIANCE community as a default build option is debatable and may be decided in due course. This code is essentially a C implementation of the prototype Python script volPhotonIllum.py. As such, it is orders of magnitude faster and more convenient, which comes to bear with large photon maps and many sensor positions. One crucial difference between the RADIANCE and Python implementations is that the former performs photon lookups in terms of a fixed number of photons around the sensor position (nearest neighbour search), while the latter does so in terms of a fixed radius (range search), and therefore does not adapt to the local photon density, which is suboptimal. The illuminance evaluated from photon flow approximates Cuttle's cubic illuminance for a virtual sensor position in a physical light field. Photon flow constitutes volume photons deposited by mkpmap in a participating medium (mist); due to the interaction of a photon with the medium, it will be deposited at multiple locations along its path; the density of these photons per path is governed by the participating medium's extinction. Evaluating cubic illuminance from photon flow entails performing volume photon lookups for each of the 6 (virtual) cube faces corresponding to 3 orthogonal axes in positive and negative directions. The resulting search volume is a hemisphere, and photons incident from the respective cube face (identified by it is normal or axis) are filtered on the fly based on their stored incident directions. This results in six independent hemispherical lookups with individual radii adapted to the density of the incident photons for each axis. Although this incurs more overhead, it was found that this approach yields consistently better results than a single lookup for all axes with a posteriori filtering, particularly with asymmetric illuminance. It was also found that the illuminance scales with the extinction of the participating medium, and is therefore corrected for the same. Generally, smaller values yield more accurate results but incur longer photon distribution times with mkpmap. The photon mapping code was modified to generate a variant of the existing volume photon map, referred to as a "lightflow photon map", which corrects the photon flux according to the extinction during it generation with mkpmap. When loaded with rtrace, a lightflow photon map triggers the cubic illuminance evaluation via the function volumePhotonCubicIllum(). Unlike the existing evaluation function for volume photons, volumePhotonDensity(), the lightflow function does not apply the Henyey-Greenstein phase function to compute outscattering (thus ignoring the participating medium), but instead performs the per-axis lookups with a volume density estimate as described above. Because photon flow not only includes photons that have been reflected off one or more surfaces (indirect contributions), but also photons that have just been emitted from light sources (direct contributions), volumePhotonCubicIllum() is is called by multiDirectPmap() in pmapsrc.c, which normally calls the direct photon map density estimate (typically only used for debugging). To prevent overcounting, the ambient calculation is therefore disabled in photon flow mode (see ampPmap() in pmapamb.c). COMPILING The photon flow code is not compiled by default as part of the RADIANCE suite, and must be enabled at compile time by defining PMAP_PHOTONFLOW. This may be accelerated by only (re)compiling in ray/src/rt if a RADIANCE build already exists: rmake OPT+=-DPMAP_PHOTONFLOW install Note that these options are independent of the underlying data structure used to store the photon map. The default options build the legacy kd-tree. If a larger, out-of-core photon map is desired (to accommodate >1 billion photons, for example), this build option must be enabled by defining PMAP_OOC: rmake OPT+="-DPMAP_OOC -DPMAP_PHOTONFLOW" install For details, see the RADIANCE Out-Of-Core Photon Map Technical Report at http://dx.doi.org/10.13140/RG.2.1.2158.9363 The photon flow code was successfully built if 'mkpmap -help' lists the '-apV' option to generate a lightflow photon map. USAGE A lightflow photon map representing the physical lightfield is generated with mkpmap by specifying the extinction of a global participating medium either on the command line, or in a RADIANCE scene description using a mist material with boundary geometry (e.g. to limit photonflow to a specific region of interest). The participating medium must not absorb nor scatter, so that a photon's trajectory is not altered as it traverses the medium. Therefore as a convenience, mkpmap implicitly sets the albedo and scattering eccentricity to 1.0, which is equivalent to specifying the options -ma 1 1 1 (no absorption) and -mg 1 (forward scattering): mkpmap -apV lightflow.vpm 1M [-apo port1 ... -apo portN] -apD 0.001 \ -me .1 .1 .1 scene.oct The extinction -me is a free parameter here and determines the photon density per path. Tests have shown that lower values improve accuracy but deposit fewer photons per path, requiring mkpmap to emit more photon paths in order to satisfy the given target photon count. There is a caveat with using higher values of -me, namely that the two-pass photon distribution algorithm used by mkpmap to achieve the target number of photons may fail. The fraction of photons emitted in the 1st pass (prepass) is specified with -apD (predistribution factor). Its default value of 0.25 is tuned for "well behaved" geometry and materials using global or caustic photons. This value may be too high for volume photons in a dense participating medium, and the photon distribution overflows in the prepass with a "photon map overflow" error, meaning that the target photon count was already exceeded (technically this does not yield an incorrect solution, but it's not what the user wanted). When using photon flow, this value may need to be significantly reduced from its default of the prepass overflows. -Once the lightflow photon map has been generated, the cubic illuminance can +Once the lightflow photon map has been generated, the RGB irradiance can be evaluated using rtrace. This evaluation is enabled when loading the lightflow photon map, which disables the normal ambient calculation. Because the ambient calculation is entirely circumvented, the -ab parameter -is now irrelevant; the volume photon density is evaluated immediately at each -sensor position. The normal vector supplied with each sensor point is currently -ignored; the axes used for the cubic illuminance coincide with the X, Y, Z -axes in global coordinates. This may be customisable in the future. - +is now irrelevant; the spherical volume photon density is evaluated immediately +at each sensor position. Each normal vector supplied with each sensor point +corresponds to the axis for each of the 6 cube faces, while the position is +(or should be!) identical for all 6 input records. Though redundant, this +parametrisation is consistent with rtrace convention. + + sensors.dat: + + <-u> + ... + + <-w> + rtrace -h -I -ap lightflow.vpm 1000 scene.oct < sensors.dat Output: - |E| ~E Esr - -In this example, the irradiance from photon flow is evaluated with a bandwidth -of 1000 photons for _each_ axis. As a convenience, the cubic illuminance -calculation implicitly converts to photonmetric values by applying the -standard luminous efficacy factor for daylight of 179 lm/W, hence it is -unnecessary to pipe the output through rcalc. - -Contrary to rtrace's default behaviour, the output for each sensor position -is NOT an RGB value, but rather a 3-tuple consisting of the illuminance vector -magnitute |E|, the symmetric illuminance ~E (approximating the mean spherical -illuminance), and the scalar illuminance Esr, which is defined as a linear -combination of the former two and thus accounts for directional and ambient -components. + + + ... + + + +In this example, the RGB irradiance E_i from photon flow is evaluated with +a bandwidth of 1000 photons for each axis i denoting one of the orthogonal +vectors {u, v, w} or its reverse. + +The cubic scalar illuminance Esr can be calculated from these values in +a separate script as a postprocess. The advantage of this discrete approach is +that it affords access to the RGB components of each axis irradiance E_i, which +would be lost if the scalar illuminance were calculated in rtrace directly. Finally, the lightflow photon distribution may be visualised by either dumping it as a RADIANCE scene description, and rendering the photons as spheres, e.g. pmapdump -n 1m lightflow.vpm | objview or by dumping it as a point list for use in a point cloud viewer: pmapdump -a -f -n 1m lightflow.vpm > photonFlow.xyz In the latter example, pmapdump also outputs each photon's radiant flux (in W) for further processing. See the pmapdump man page or the RADIANCE photon map manual at http://dx.doi.org/10.13140/RG.2.1.4330.8405/1 for details. CONCLUSION Having reassessed the approach to evaluate cubic illuminance from volume photons, revised the code accordingly, and tested it with asymmetric illuminance distributions, I feel this release is easier to use, better integrated into the existing RADIANCE framework, and more stable and mature. However, the code, like the approach it implements, is still experimental and needs some more testing in "real world" scenarious, so I welcome your feedback in terms of its results, but also its usage. Once we are confident with the results, we should make the code public and upload it to the RADIANCE CVS repository. Initially, though, it would be prudent to still leave photon flow an option for advanced users only. Many thanks in advance for your cooperation and feedback. Happy photon flowing! --Roland Schregle (roland.schregle@{hslu.ch, gmail.com})