[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] lighting challenge



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 :)