POV-Ray : Newsgroups : povray.binaries.images : Light Fading Documentation Error : Light Fading Documentation Error Server Time
7 Nov 2024 02:23:30 EST (-0500)
  Light Fading Documentation Error  
From: Cousin Ricky
Date: 25 Dec 2016 14:43:03
Message: <58602147$1@news.povray.org>
It is well known that POV-Ray'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 POV-Ray 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 hard-coded 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 hard-coded 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 radiosity-only 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 POV-Ray 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 non-linear 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'
light_fade_formula1.png

Preview of image 'light_fade_formula2.png'
light_fade_formula2.png

Preview of image 'light_fade_formula3.png'
light_fade_formula3.png

Preview of image 'light_fade_formula4.png'
light_fade_formula4.png


 

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.