Gaussian specular in UnrealEngine4

Started by
8 comments, last by MJP 11 years, 6 months ago
So I was reading in the unreal engine 4 siggraph paper about their usage of an empirical model for this.
If you haven't seen it it's on page 30 or so: http://www.unrealeng...mo_16x9_(2).pdf

Now the only thing I was wondering is this model as it is stated in the paper, is not normalized as it seems.
And as far as the code is concerned they only describe this factor for their area light sources.
Does anyone have an idea of what the correct normalization factor for this specific model would be for a regular punctual light source ?
Advertisement
Unfortunately I couldn't solve it analytically (I doubt it's even solvable this way), but I came up with a simple aproximation: 0.17287429 + 0.01388682 * n. Where n is Blinn-Phong specular power. It's quite accurate for specular powers above 16. If you are interested I have posted some plots on my blog: http://kriscg.blogsp...n-specular.html .

Unfortunately I couldn't solve it analytically (I doubt it's even solvable this way), but I came up with a simple aproximation: 0.17287429 + 0.01388682 * n. Where n is Blinn-Phong specular power. It's quite accurate for specular powers above 16. If you are interested I have posted some plots on my blog: http://kriscg.blogsp...n-specular.html .


splendid! :)
I've implemented it for Disney's BRDF Explorer and evaluated how closely it fits the Mitsubishi MERL BRDF database. I found out, that its shape is pretty unrealistic. Also, KriScg's approximation was off by about the factor 2.

Here's the better approximation of the NDF:
d_mittring.png

Also here's a plot of its shape compared to the more physically correct GGX distribution function:

plot_mittring_ggx.png

It's actually even slower than GGX, so why would anyone want to use it anyway huh.png
Yeah I've also been a bit confused as to why they're going with that BRDF. GGX is really nice, and I find it works well for a lot of materials.
KriScg's approximation was off by about the factor 2.


I think it's because you are using wrong treshold 0.004 (it was 0.04 in the presentation).

Yeah I've also been a bit confused as to why they're going with that BRDF. GGX is really nice, and I find it works well for a lot of materials.


We're talking about the same Epic/Unreal engine, right? I can probably count on one hand the number of 'yes, *this* is a smart renderer design decision' moments in recent memory :(

I mean, look at the entire HDR pipeline in UE3.
clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.

[quote name='CryZe' timestamp='1350141452' post='4989792']KriScg's approximation was off by about the factor 2.


I think it's because you are using wrong treshold 0.004 (it was 0.04 in the presentation).
[/quote]
Oh wow, I didn't even realize that. I might fix my post, after I've tried the correct version.

Edit: Overall, nothing really much changed, except the fact, that the approximation is still off, but not by a factor of 2. The problem is, that you want the integral to evaluate to 1 and not to "<= 1".

The problem is, that you want the integral to evaluate to 1 and not to "<= 1".


I did solve it for integral = 1. I just wrote it as <= 1. Thanks for noticing.

I wrote a brdf for BRDF explorer with "Mittring" specular.

[source lang="plain"]analytic

::begin parameters
float n 1 1000 100
bool normalized 1
::end parameters

::begin shader

vec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y )
{
vec3 H = normalize( L + V );
float Dot = clamp( dot( N, H ), 0, 1 );
float Threshold = 0.04;
float CosAngle = pow( Threshold, 1 / n );
float NormAngle = ( Dot - 1 ) / ( CosAngle - 1 );
float D = exp( -NormAngle * NormAngle );

if (normalized)
{
D *= 0.17287429 + 0.01388682 * n;
//D *= 0.34574858 + 0.02777364 * n;
}

return vec3(D);
}

::end shader[/source]

Now when you use mine aprox, then max albedo in BRDF explorer correctly comes up as 1, but when using yours it's 2. This means, that in yours aprox sometimes outgoing energy is two times greater than incoming. I believe it's because you did integrate over full sphere, instead of just upper hemisphere.


We're talking about the same Epic/Unreal engine, right? I can probably count on one hand the number of 'yes, *this* is a smart renderer design decision' moments in recent memory sad.png



I don't think that's particularly fair. They have plenty of good tech, and lots of people have made really good games with it.

Anyway I wasn't implying that they made the wrong decision with their choice, just that I didn't understand the motivation behind it.

This topic is closed to new replies.

Advertisement