1
$\begingroup$

I'm playing with a grid-based lighting system, where light is transported and accumulated through a grid. I initially tried attenuation based on 1/(distance*distance), but that doesn't work when the distance between each node is 1.

Here's a picture

I tried hacks like adding an epsilon or clamping the distance, but nothing looks right. I'm sure there's something obvious I'm missing. Any guidance?

$\endgroup$
  • $\begingroup$ Perhaps I'm misunderstanding what you're doing, but why does the light increase from 1 to 4 at a distance of 0.5? Shouldn't it decrease everywhere that's not the center of the light? $\endgroup$ – user1118321 Mar 2 '18 at 3:13
  • $\begingroup$ It increases because I am using 1/(distance*distance) as falloff, so 1/(0.5*0.5) = 4 $\endgroup$ – Anthony Mar 3 '18 at 13:43
  • $\begingroup$ Are you like... propagating your light one grid cell at a time, without knowing where it originally came from? That's a bit what it looks like but I'm uncertain I understand what you're trying to do. $\endgroup$ – Olivier Mar 4 '18 at 15:13
  • $\begingroup$ Yep. Each cell stores its light output in various directions. A shader runs for each grid cell, and is responsible for taking light from neighboring cells, casting it through the current cell (reflecting it if it hits something, in this case it doesn't), and writing the result to the current cell. So I always know the position and approx direction of the light, but I don't know where it came from (because all light in a particular direction is combined) $\endgroup$ – Anthony Mar 4 '18 at 16:21
1
$\begingroup$

It looks to me like you're resetting the distance calculation at each grid intersection? So every time you march another grid cell you're dividing the light intensity by $gridsize^2$ ? That would explain your observed results, since dividing by $1^2$ equals no change. It won't give you the correct result though, since to get the right attenuation you need to track the total distance back to the light source and square that.

Also note that the attenuation term used in rendering is usually a bit more complicated than just $1/D^2$ - generally it's a quadratic, $1/(aD^2 + bD + c)$. While not physically correct, it's more tunable and easier to get visually pleasing results. In your case, for example, using $1/(D^2 + 1)$ would prevent the edges immediately surrounding the light from being brighter than the light itself.

$\endgroup$
  • $\begingroup$ At the first boundary, wouldn't D^2 + 1 be 1.25? $\endgroup$ – user1118321 Mar 3 '18 at 5:21
  • $\begingroup$ Yeah, so you'd have an intensity of 0.8 $\endgroup$ – russ Mar 3 '18 at 9:26
  • $\begingroup$ "to get the right attenuation you need to track the total distance back to the light source and square that" Why is that? What is the difference between a light source with intensity 1 at distance 2 and a light source with intensity 0.25 at distance 1? The +1 constant does get more reasonable results, but it still doesn't seem physically correct. I'll look at tracking individual rays/distances, but I was hoping to aggregate light at each point in the grid, so I don't "know" the original distance. $\endgroup$ – Anthony Mar 3 '18 at 14:06
  • $\begingroup$ Because the distance to the original light is what matters for intensity. The ratios of the squares change as you move away from the light. Let's say you have a grid size of 2 - when moving from distance 2 to distance 4, the light should get 4x dimmer, but when moving from distance 10 to 12 it will only get 1.44x dimmer. $\endgroup$ – russ Mar 3 '18 at 14:28

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.