diff --git a/README-photonflow.txt b/README-photonflow.txt index 4eb43ab..39ef716 100644 --- a/README-photonflow.txt +++ b/README-photonflow.txt @@ -1,226 +1,261 @@ 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 Similar to stanard (planar) photon mapping, photon flow supports kernel density estimates by weighting individual photon contributions by their inverse distance to the lookup point. This filter reduces bias, and can be enabled with the following: rmake OPT+=-DPMAP_EPANECHNIKOV -DPMAP_OOC -DPMAP_PHOTONFLOW" install This command enables the 3D Epanechnikov kernel (1 - (d_i)^2), where d_i is the normalised distance between the lookup point and photon (i). The bias reduction is moderate, however, and ineffective with excessive lookup bandwidths. Finally, the following checks verify that the photon flow code was successfully built: 1. 'mkpmap -help' lists the '-apV' option to generate lightflow photon maps, 2. 'rtrace -help' lists the '-aS' option to toggle between planar and spherical illuminance evaluation from lightflow photons. 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 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 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: ... 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. In addition, the mean spherical irradiance can be calculated with rtrace to compare with the cubic scalar illuminance Esr. Rtrace accepts a boolean option -aS to toggle between the planar irradiance evaluation for E_i as above (corresponding to the default -aS-), and the mean spherical irradiance evaluation using -aS+ (or just -aS): rtrace -h -I -ap lightflow.vpm 1000 -aS+ scene.oct < sph_sensor.dat Note that the normal vector specified for the sensor position is irrelevant and ignored for this evaluation. 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. +TRANSIENT PHOTON FLOW + +An experimental variant of the light flow photon map that supports transient +(i.e. time-dependent) rendering is currently being tested. This variant +tags each photon with its corresponding path length, which corresponds to +a time stamp. In order for the time stamp to be physically valid, the user +must specify the speed of light in units of scene geometry (i.e. a multiple +of approx. 3e8 m/s) when generating the photon map with mkpmap. This constant +is specified in addition to the photon map size with the type-specific -apT +option: + + mkpmap ... -apT lightflow.tpm 1M 3e8 ... scene.oct + +Transient lightflow can then be evaluated as a spatio-temporal function by +specifying a point in time in addition to a position: + + rtrace -h -I -ap lightflow.tpm 250 1.6e-9 scene.oct < sensor.dat + +In the above example, the irradiance/illuminance will be evaluated at +the given sensor position AND the given time: 1.6 nsec after photon emission +begins. + +This spatio-temporal distribution can also be visualised by passing +the parameters into rpict, which leads to surprising effects. To this end, +the Python script transpmap.py is being developed to render spatio-temporal +light flow sequences and merge these into a video. For example, the commands + + transpmap.py -t 0 -T 8e-9 -d 1e-10 -p 10m -b 250 -n 8 cornell.vf cornell.oct + +will render transient lightflow from 10 million photons with a bandwidth of +250 photons on 8 cores within the time interval [0, 8 nsec] in increments +of 100 psec per frame. See 'transpmap.py -h' for the supported options. + + + 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})