The Persistence of Vision Raytracer (POV-Ray).
This is the legacy Bug Tracking System for the POV-Ray project. Bugs listed here are being migrated to our github issue tracker. Please refer to that for new reports or updates to existing ones on this system.
FS#264 - Improve precision of photon direction information
Attached to Project:
POV-Ray
Opened by Christoph Lipka (clipka) - Friday, 04 January 2013, 23:39 GMT
Last edited by William F Pokorny (wfpokorny) - Tuesday, 25 April 2017, 12:21 GMT
Opened by Christoph Lipka (clipka) - Friday, 04 January 2013, 23:39 GMT
Last edited by William F Pokorny (wfpokorny) - Tuesday, 25 April 2017, 12:21 GMT
|
DetailsIn the photons map, the direction of each photon is stored as separate latitude & longitude angles (encoded in one byte each), causing the longitudinal direction component’s precision to be unnecessarily high for directions close to the “poles” (Y axis); in addition, encoded value -128 is never used. For better overall precision as well as precision homogenity, the following scheme could be used instead:
latCode = (int)((LatCount-1) * (lat/M_PI + 0.5) + 0.5)
LC = LngCount[latCode]; lngCode = (int)(LC * (lng/(2*M_PI) + 0.5) + 0.5) % LC;
dirCode = LatBase[latCode] + lngCode;
|
This task depends upon
A relevant paper for this task:
http://faculty.cs.tamu.edu/schaefer/research/normalCompression.pdf
Thanks for the reference, Simon. Looks like exactly the same basic idea, except that they used a more precise formula for LngCount[] (which they call N[Theta]), and add a few more ideas on top of that. Unfortunately their main focus appears to be variable-length encoding into a bit stream, while our problem is fixed-length encoding, so the actual steps of encoding latCode and lngCode into a single fixed-width value, and decoding that value into latCode and lngCode again, are not addressed by the paper.
I was thinking a bit about this, and came to the following conclusion:
If you encode the precomputed map in 8-bit precision, there is no reason to encode at all. You don't save any space with that. A look at the code shows that the photon structure is
float[3] #location (12 bytes)
char[4] #color (4 bytes)
char #info (1 byte)
char[2] #direction information (2 bytes)
On all modern architectures, the memory alignment is at least 4, if not 8 bytes, so the entire structure is packed into 20 bytes (sizeof(Photon) on gcc 4.7.2, x86_64). Having char[3] for location would have the same precision as a 8-bit precomputed list, and would take no more space in the structure. Encoding only makes sense if you save space or increase precision by using it. I think that having simply char[3]=(x,y,z) for direction is just fine if you decide for 8-bit precomputation - simplicity over obfuscation :)
For our specific case, the location data takes much more space than the direction anyway, and it cannot really be reduced, because you need sharp location for accurate caustics.
Edit: for 8-bit encoded components, you need normalization after conversion to float (so this precomputation does not help increase speed). So:
if you keep it as is, you have precomputed sin/cos values (fast)
if you make the encoding more complicated (more accuracy), you can either have built-in char[3] (simple but slow because of required renormalization) or 16-bit encoding with global float[3] lookup table (fast and more precision).
Or, of course, you can ignore that 8-bit precision can result in vector length a bit different than 1 and live with the consequences.
Now tracked on github as issue #283.