Sign in to follow this  
Hodgman

Spherical Area Lights

Recommended Posts

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:
7zrUFwf.png
[edit] Disney use this version, which is also exactly equivalent to the above versions:
oPsegzj.gif
 

https://www.shadertoy.com/view/4ss3Ws

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?? laugh.png

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 wacko.png

 

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

 

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

http://imgur.com/a/bluzs

Edited by Hodgman

Share this post


Link to post
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 this post


Link to post
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 smile.png

Share this post


Link to 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:

yDvqmjb.png

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

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

Kq8FCj6.png

 

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

Edited by Hodgman

Share this post


Link to post
Share on other sites

https://www.shadertoy.com/view/4ss3Ws

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 wacko.png

Actually, that formula is taken straight from the presentation from the Specular D Modification section. Now I feel a bit stupid wacko.png
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! unsure.png

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

Share this post


Link to 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:

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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this