On 2015-07-07 06:04, Ian Mallett wrote:
Hi,
The basic idea with what I gave is to compute the simplest light
transport paths from the light to the eye. Specifically, we want all
paths that start at the light, pass through some number of surfaces,
scatter off another surface, pass through some number of surfaces, and
then hit the eye.
I've added some comments to my pseudocode, which I've also edited a bit.
#Start with no light
result = 0
for S in surfaces:
#On this loop iteration, we will consider the
# light path that starts at the light, travels
# to S, bounces off, and travels to the eye.
#Figure out the amount of light that gets from
# the light to the surface.
product_of_alphas_between_light_and_S = 1.0
for T in surfaces:
if T is between S and the light:
#Attenuate light by T's transmissivity
# (alpha in range [0.0,1.0]).
product_of_alphas_between_light_and_S *= T.alpha
#"product_of_alphas_between_light_and_S" should
# now be a number between 0.0 and 1.0. It
# represents the attenuation of the light
# as it travels to S.
#This tell you how much light gets to S. The
# "intensity" scales how "strong" the light is.
# Technically, it's radiance, not intensity.
light_at_surface = light_intensity *
product_of_alphas_between_light_and_S
#Some of the light will be absorbed or transmitted
# through S. The amount that is scattered back
# in a particular direction is called the BSDF.
# The BSDF I'm using here is diffuse, which is a
# constant factor (surface reflectance). Because
# energy is conserved, this factor cannot be
# negative or larger than 1.0.
#Ultimately, this tells how much light leaves the
# S heading toward the eye.
reflected_light = light_at_surface * surface_reflectance
#Same idea as above. Here we're attenuating the
# reflected light as it travels from S to the eye.
product_of_surface_alphas_between_S_and_eye = 1.0
for T in surfaces:
if T is between S and the eye:
product_of_surface_alphas_between_S_and_eye *= T.alpha
#This is the amount of light that finally reaches
# the eye.
light_at_eye = reflected_light *
product_of_surface_alphas_between_S_and_eye
#Accumulate it. The sum of all paths (in all the
# loop iterations) is the first order light
# transport between the light and the eye.
result += light_at_eye
HTH,
Ian
Hi Ian
Sorry for the long delay, other things kept me busy.
Thank you for your comments. I now see what you were telling me. In
short (its like raytracing or similar):
Go along the light and see what is filtered, reflected and filtered
until reaching the eye.
I think I understand your pseudo code now. I still have some
difficulties translating it into blit operations.
https://bitbucket.org/dr0id/pyknic/downloads/2015-08-05-lighting.zip
Take a look at the tile 10 (the d raw10(...) method in code on line 886
in lighting.py). There, I try to implement what you proposed, but I seem
to do something wrong. Comparing with 9 (which is my reference now), it
does not the same thing. Ok, maybe when using multiple lights it has to
be done differently, but I thought it should not be that different.
Maybe you can hint me in the right direction, because I don't like the 3
surface.copy() that are done in the algorithm 9.
By the way, make sure to read the help (press TAB) because I have
changed the key mapping because I was running out of keys (Keys 1-0 now
change the scene, space starts some simple animation in certain scenes).
But you will figure it out.
Thanks.
~DR0ID
PS: next week I will be busy with pyweek :)