Post by markf on May 6, 2019 1:41:24 GMT
Hi everyone,
I implemented multiple light sources a short while ago. Very neat looking. I thought I would give area lighting a try, but was pretty intimidated by the cost and complexity of that feature. I also thought that an area light was really as artificial as a point light. So I thought perhaps a better way of thinking of a light source would be as something that emits rays from a point with a normal (i.e., Gaussian) distribution about the center of the light.
So I started with a random number generator with a normal distribution, with an average of zero and a standard deviation of one. I added two new attributes to the point_light structure; radius and iteration, with defaults of zero and one. These defaults make the light behave exactly like the default point light. But if you set the radius to something a bit wide and use a reasonable iteration count, you can get some decent results. Here are two rendered scenes using a radius of 0.5 and an iteration count of 40. One scene has a single light source and the other has two, with their intensities in the second scene set to (0.5 0.5 0.5)
Rendering these scenes come at a cost of course, but you can always play with the light settings. Even an iteration count of 5 gives you a good idea of what you'll get, and you can bump the iteration count up for the final render.
I'm still finishing up the code and adding a description of how it all works, which I'll post for comment and critique. Basically though, I keep the old is_shadowed() function and create a new is_shaded() function that returns a value between 0 (fully shadowed) and 1 (no shadow). If radius is zero, just return the complement of is_shadowed(), otherwise iterate and average the results of is_shadowed() where the light source point is offset by a random distance along each axis. The offset is proportional to the radius, and best results are obtained by using a new random number for each axis.
The lighting() function then uses the scaled value from is_shaded() and multiplies the diffuse and specular values by it when summing the three color components. I'm not quite sure I should also be jittering the light source for the lighting() function as well. More experimenting needed. When compared to the rendering time for a single point light source, the first image took about 11 times longer and the second about 22 times longer.
Cheers,
~Mark
I implemented multiple light sources a short while ago. Very neat looking. I thought I would give area lighting a try, but was pretty intimidated by the cost and complexity of that feature. I also thought that an area light was really as artificial as a point light. So I thought perhaps a better way of thinking of a light source would be as something that emits rays from a point with a normal (i.e., Gaussian) distribution about the center of the light.
So I started with a random number generator with a normal distribution, with an average of zero and a standard deviation of one. I added two new attributes to the point_light structure; radius and iteration, with defaults of zero and one. These defaults make the light behave exactly like the default point light. But if you set the radius to something a bit wide and use a reasonable iteration count, you can get some decent results. Here are two rendered scenes using a radius of 0.5 and an iteration count of 40. One scene has a single light source and the other has two, with their intensities in the second scene set to (0.5 0.5 0.5)
Rendering these scenes come at a cost of course, but you can always play with the light settings. Even an iteration count of 5 gives you a good idea of what you'll get, and you can bump the iteration count up for the final render.
I'm still finishing up the code and adding a description of how it all works, which I'll post for comment and critique. Basically though, I keep the old is_shadowed() function and create a new is_shaded() function that returns a value between 0 (fully shadowed) and 1 (no shadow). If radius is zero, just return the complement of is_shadowed(), otherwise iterate and average the results of is_shadowed() where the light source point is offset by a random distance along each axis. The offset is proportional to the radius, and best results are obtained by using a new random number for each axis.
The lighting() function then uses the scaled value from is_shaded() and multiplies the diffuse and specular values by it when summing the three color components. I'm not quite sure I should also be jittering the light source for the lighting() function as well. More experimenting needed. When compared to the rendering time for a single point light source, the first image took about 11 times longer and the second about 22 times longer.
Cheers,
~Mark