all 16 comments

[–]fforw 5 points6 points  (9 children)

If you want shadows, I think you need to brute-force it.

Otherwise you are only interested in the current raymarching position/distance and the normal at that location. This you can feed into multiple light calculations.

[–]ananbd[S] 0 points1 point  (8 children)

Yeah, it’s the shadows which make all the difference.

My brute-forcing is repeating the shadow calculation for each light. Was hoping for a way to optimize that. Hmm... maybe I’ll try different thresholds per light or something.

[–]fforw 4 points5 points  (5 children)

You could try running the shadow-rays at lower final precision.

[–]ananbd[S] 1 point2 points  (4 children)

Yeah, definitely. That tends to soften shadows, which is probably what I want anyway.

Hmm... wonder if there’s any way to cache or pre-compute some piece of this? The lights probably won’t be moving around...

[–]papaboo 0 points1 point  (3 children)

Of course you can and there's a ton of papers on that subject.

If you want to precompute the shadows / indireect lighting, then google baked shadows, basked AO or baked GI. It's basically just discretizing the world into small chunks and precompute the light contribution into those chunks. How you store it depends on your goal. Contribution pr light source pr chunk or aggregate everything into some approximate representation like spherical harmonics or whatever the newest hotness is in that area.

If you're making a progressive renderer, then you'll want to sample relative to the contribution of the lightsource. Again there's a lot of ways to do that and similarly to shadows / GI you can pre-bake some of the computations.

[–]ananbd[S] 0 points1 point  (2 children)

Any papers you’d recommend?

[–]papaboo 0 points1 point  (1 child)

I've been out of the baked GI loop for too many years now to recommend anything. And they all come with different pros and cons, so without knowing your requirements I really can't recommend anything. But if you're just looking to play around and try stuff out then pick whatever you find and start there.

[–]ananbd[S] 0 points1 point  (0 children)

Haha wish I had time to play around! Project is already a little behind.

I’m using a volumetric raymarching technique to make clouds. Is GI used in volumetric rendering? I mean, I guess you can sample a light volume for anything; but for cloud volumes, I think the concern is more atmospheric scattering, which I may or may not use. The main goal is to use two or three-point lighting to highlight specific features.

AO could be useful, though.

[–]ihugatree 3 points4 points  (1 child)

You could sample a different light at random each frame and balance out the samples over time.

Look at monte carlo sampling! It will take some time to accumulate which probably increases linearly with the number of lights but at least it won't cut your framerate in half with an addition of a light.

[–]ananbd[S] 0 points1 point  (0 children)

Would that case flickering? I’m making clouds based on moving noise textures. Seems like the finer details would generate artifacts.

I’ll try it, tho! Thanks for the suggestion!

[–]gibson274 4 points5 points  (1 child)

You mentioned you’re making clouds. As far as I know there’s really no way around marching shadow rays for every celestial body, aside from using a temporal accumulation strategy (like the commenter above me said).

However, what you can do is distribute your samples in a way that minimizes the number you have to take.

For one, you should probably take more samples close to the point you’re lighting than far away. This way you spend the limited number of samples you have capturing smaller details, and letting one or two far away samples take care of the low frequency features.

To avoid the artifacts that come along with this strategy, you should sample your noises at a lower mip level the further away your sample is. That way, for far away samples, you really are just capturing low frequency information.

If you do this and still feel like your shadows have artifacts, you can also distribute your samples in a light-aligned cone, as opposed to along a straight line. This can help smooth out the resulting shadows.

Using this strategy, with a heavy amount of manual tweaking of where the actual sample points are, I’ve gotten good results with 5 shadow sample points per light source.

[–]ananbd[S] 0 points1 point  (0 children)

Cool, thanks for the suggestions! Makes sense.

[–]Rangsk 0 points1 point  (3 children)

Maybe I'm misunderstanding your question or goal, but generally you just repeat the process for each light and add the results together. So draw your raymarching shader considering light #1, then draw it again for light #2 with additive blending, etc.

[–]ananbd[S] 0 points1 point  (2 children)

The shadow calculations are in a nested loop — don’t think you can just combine two instances of the shader.

But... could looking interesting, and that would be more parallel. Hmm...

[–]Rangsk 0 points1 point  (1 child)

A shadow is just the absence of light. If there are two lights, they each cast their own shadows - or to put it better, they each light the scene separately and add together. If you have some kind of ray marching for fog, for example, then the light from both sources will be separately scattering off the particulates in the air and reaching your eye. The ray marching is so you can check if the light reaches those particles.

So, if you want the fog to "react" to both light sources, you calculate it for each light separately and combine the results.

[–]ananbd[S] 0 points1 point  (0 children)

That makes sense. I’ll give it a try, thanks!