

It is well known that POVRay's light_source attenuation does not use
true Newtonian fading (prior to 3.7.1, anyway). To mitigate this, the
3.7 user manual suggests the formula
Intensity_Factor = function (LD,FD,FP) {pow(1+(LD/FD),FP)/2}
where Intensity_Factor() is a multiplier for the light source color, LD
is the nominal fade distance, FD is a very small number to serve as the
actual fade_distance, and FP is the fade power.
The user manual section in question is at
http://wiki.povray.org/content/Reference:Light_Source#Light_Fading
Back when POVRay 3.7.0 was being finalized, I noticed that this formula
seemed to be incorrect, and I posted my concern to to p.d.i in March
2013. I proposed that the proper formula is {(1+pow(LD/FD,FP))/2}.
James was skeptical, saying that he correctly copied the formula from
his source, but didn't check the math. I had checked the math, but no
further action was taken.
I finally got around to creating a test scene. It is to be rendered as
an animation in 4 frames.
[BEGIN CODE]
// +kff4
#version 3.7;
#include "screen.inc"
#include "strings.inc"
global_settings
{ assumed_gamma 1
radiosity
{ count 2000
error_bound 0.5
pretrace_start 16 / image_width
pretrace_end 1 / image_width
recursion_limit 2
}
}
Set_Camera (<0, 1, 5.6713>, <0, 0.50065, 0.02203>, 31.5100)
box
{ <7, 9, 7>, <7, 9, 7> hollow
pigment { rgb 1 }
}
plane
{ y, 0
pigment { checker rgb 0.05 rgb 1 }
}
#declare LD = 1;
#declare FD = 0.25;
#declare s_Functions = array[4][2]
{ { "pow(1+(LD/FD),2)/2", "(3.7 manual)" },
{ "(1+pow(LD/FD,2))/2", "(my correction)" },
{ "Radiosity only", "(control)" },
{ "Traditional fade_distance", "(control)" },
}
#switch (frame_number)
#range (1, 2)
light_source
{ LD * y, rgb Parse_String (s_Functions [frame_number  1][0])
fade_power 2 fade_distance FD
}
#break
#case (3)
sphere
{ LD * y, FD
pigment { rgb 1 }
finish { ambient 0 diffuse 0 emission pow (LD / FD, 2) }
}
#break
#case (4)
light_source
{ LD * y, rgb 1
fade_power 2 fade_distance LD
}
#break
#end
Screen_Object
( text
{ ttf "cyrvetic" s_Functions [frame_number  1][0] 0.0001, 0
pigment { red 1 }
finish { diffuse 0 emission 1 }
scale 0.075
},
<0, 1>, <0.02, 0.02>, yes, 1
)
Screen_Object
( text
{ ttf "cyrvetic" s_Functions [frame_number  1][1] 0.0001, 0
pigment { red 1 }
finish { diffuse 0 emission 1 }
scale 0.075
},
<1, 1>, <0.02, 0.02>, yes, 1
)
[END CODE]
The nominal fade distance (LD) for all frames is from the light source
to the floor.
 Image light_fade_formula1.png uses the formula from the user manual.
Note that I hardcoded the FP parameter as 2, as I have yet to use
any other value, and don't foresee any future change to that trend.
 Image light_fade_formula2.png uses the formula I derived from the
internal attenuation equation as documented in that same section of
the user manual. Again, the FP parameter is hardcoded as 2.
 Image light_fade_formula3.png is a control scene that uses radiosity
only. The radius of the glowing sphere is FD, and its emission
value is the square of the LD/FD ratio. Aside from the radiosity
artifacts, this is the benchmark for physical realism.
 As a second control, image light_fade_formula4.png uses the
traditional method, with fade_power 2 and fade_distance literally
from the light source to the floor.
My formula (frame 2) is closest to the radiosityonly control (frame 3)
at all distances from the light source. The user manual formula (frame
1) is noticeably brighter. The traditional method (frame 4) is a tad
brighter than frame 1 at the back wall, but matches frames 2 and 3
directly beneath the light source.
Frame 4 is correct, by definition, directly beneath the light source
(though nowhere else); and frame 3 is a physical simulation that is
theoretically correct at all points. Since frame 2 matches all these
points, and frame 1 does not, my formula appears to produce the correct
results. Also, substituting LD for FD should yield a multiplier of one.
This is indeed the case with my formula, but not with the user manual
formula. I therefore conclude that my formula is the correct one, and
the suggested formula in the documentation should be amended accordingly.
P.S. I had always assumed that the reason POVRay used an attenuation
formula that maxed out at 2 was to cope with limited dynamic range. But
with CLipka's recent gamma thread and the brightness of the back wall in
frame 4, it occurred to me that this might be another nonlinear gamma hack.
Post a reply to this message
Attachments:
Download 'light_fade_formula1.png' (16 KB)
Download 'light_fade_formula2.png' (16 KB)
Download 'light_fade_formula3.png' (18 KB)
Download 'light_fade_formula4.png' (15 KB)
Preview of image 'light_fade_formula1.png'
Preview of image 'light_fade_formula2.png'
Preview of image 'light_fade_formula3.png'
Preview of image 'light_fade_formula4.png'




Am 25.12.2016 um 20:45 schrieb Cousin Ricky:
> It is well known that POVRay's light_source attenuation does not use
> true Newtonian fading (prior to 3.7.1, anyway). To mitigate this, the
> 3.7 user manual suggests the formula
>
> Intensity_Factor = function (LD,FD,FP) {pow(1+(LD/FD),FP)/2}
...
> Back when POVRay 3.7.0 was being finalized, I noticed that this formula
> seemed to be incorrect, and I posted my concern to to p.d.i in March
> 2013. I proposed that the proper formula is {(1+pow(LD/FD,FP))/2}.
I haven't verified your claims regarding the test images, but from the
maths I come to the same conclusion as you do.
The docs say, "The following example, that takes the inverse of the
above formula [...]"  here, "inverse" needs to be interpreted as
"reciprocal", i.e. the multiplicative inverse of the attenuation, not
some inverse function mapping the attenuation back to distance.
As such, this "inverse" is easily computed by swapping the numerator and
denominator of the attenuation formula.
> James was skeptical, saying that he correctly copied the formula from
> his source, but didn't check the math. I had checked the math, but no
> further action was taken.
My geuss that it drowned in the height field related portion of the
thread, and I'd recommend you bring this to Jim's attention again.
> P.S. I had always assumed that the reason POVRay used an attenuation
> formula that maxed out at 2 was to cope with limited dynamic range. But
> with CLipka's recent gamma thread and the brightness of the back wall in
> frame 4, it occurred to me that this might be another nonlinear gamma
> hack.
My personal bet would be that it has nothing to do with gamma, but that
the author was a bit more afraid of dividebyzero errors than necessary
in this case.
Or that person did indeed intend to model a light source of
noninfinitesimal size.
Post a reply to this message

