# Spherical Area Lights

This topic is 2095 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

##### Share on other sites

The formula given in the paper needs to be converted from angles to vectors before being used in shader code, and it can be rearranged quite a bit too, which is why it often looks different.

I have:
D = ( roughness  / (    dot(N,H)2*(roughness2-1)+1) )2
...and later: Lighting /= Pi;
But Brian Karis (author of the above presentation) has:
D =   roughness2 / Pi*( dot(N,H)2*(roughness2-1)+1)2

I just had a moment of panic thinking that my D term was completely different to his, but they're both exactly equivalent. If you chuck either of them into wolfram alpha, it spits out the alternate form at the bottom:

 Disney use this version, which is also exactly equivalent to the above versions:

Thanks!

Their normalization term seems to be completely arbitrary, being connected to an arbitrary tweakable variable, and commented with //not sure at all about this??

The version that that's derived from (https://www.shadertoy.com/view/ldfGWs) uses this normalization term:

norm = saturate(radius / ( distance * 2.0 ) + roughness2)2

...but this doesn't seem to work for me (energy still isn't conserved), and I have no idea how they derived this formula from Brian's presentation

The different shaped area lights are awesome in those demos though!

Here's some Gifs comparing my normalization term compared to the above formula:

http://imgur.com/a/bluzs

Edited by Hodgman

##### Share on other sites

The formula given in the paper needs to be converted from angles to vectors before being used in shader code, and it can be rearranged quite a bit too, which is why it often looks different.
Ok, but the last time I checked GGX on being normalized I actually got 1. Have you forgotten to include the cosinus term perhaps?

##### Share on other sites

The formula given in the paper needs to be converted from angles to vectors before being used in shader code, and it can be rearranged quite a bit too, which is why it often looks different.

Ok, but the last time I checked GGX on being normalized I actually got 1. Have you forgotten to include the cosinus term perhaps?

Yeah I confused myself, because when I originally switched over to GGX, I rearranged the equation (as above), to pull out the division by Pi. My diffuse light also has to be divided by Pi, so I moved this operation right to the end, after all the lights have been summed.

If I undo that optimization and put the Pi back into the GGX function, then it does integrate to 1 over the hemisphere, instead of Pi (so the normalization term is 1, not 1/Pi).
Edited my first post

##### Share on other sites

I was plotting some values and noticed that the sin2 term looked just like the smoothstep function, and it turns out that it's coincidentally very close:

So I fitted the sin-1 term to a polynomial, and ended up with a trig-less approximation, which looks almost idential:

poly = 0.72216935842*n2 + 0.57534745225*n + 0.04360349982*saturate(n*10);
norm = saturate(roughness2 / (3*poly2 - 2*poly3)) //smoothstep

I don't know how expensive trig functions are in shaders these days, so it's a completely premature optimization  but it's nice to know I can remove those trig functions if I need to.

Edited by Hodgman

##### Share on other sites

The version that that's derived from (https://www.shadertoy.com/view/ldfGWs) uses this normalization term:
norm = saturate(radius / ( distance * 2.0 ) + roughness2)2
...but this doesn't seem to work for me (energy still isn't conserved), and I have no idea how they derived this formula from Brian's presentation

Actually, that formula is taken straight from the presentation from the Specular D Modification section. Now I feel a bit stupid
Except the above isn't right, according to the presentation, it should be:
norm = ( roughness / saturate(radius/(distance*2) + roughness) )2

Ok... well, the results of that formula are looking better than my formula!

I'll look at the math some more and post some more Gifs later

##### Share on other sites

I was plotting some values and noticed that the sin2 term looked just like the smoothstep function, and it turns out that it's coincidentally very close:

That's basically how the vegetation's wind animation in Crysis has been optimized: https://developer.nvidia.com/content/gpu-gems-3-chapter-16-vegetation-procedural-animation-and-shading-crysis

I'm always using  x * x *( 3.0 - 2.0 * x ) instead of Smoothstep, which I think is often times more optimal since Smoothstep maps the input to the range [0..1] at first even if it is already in this required range.

• 18
• 19
• 11
• 21
• 16