# Oren-Nayar with Blinn-Phong Specular

## Recommended Posts

L. Spiro    25620

In the physically based Blinn-Phong equation presented by my own company, tri-Ace, the specular is multiplied by the Fresnel term and the diffuse is thus multiplied by (1 - Fresnel) in order to maintain energy conservation.

It is the first equation in this paper: http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf

Oren-Nayar by itself is energy-conservative when considering only the diffuse term, so logically if you want to add some specular you have to somehow modify the diffuse.

I am adding the specular component of Blinn-Phong from that paper and am not sure how to correctly adjust the diffuse term.

My initial thought was to do the same as before, by multiplying it by (1 - Fresnel).  But Oren-Nayar is already view-dependent and that is like doubling its view-dependence.

Is it as simple as I thought or is it more complicated to normalize the combination of specular and diffuse here?

What do I need to know in order to balance speculars and diffuses of other models on my own without having to run online every time?

Looking at Cook-Torrance here, the diffuse term is just Lambert.  That is not physically plausible, is it?

How do you make it so?

L. Spiro

#### Share this post

##### Share on other sites
EarthBanana    1794

I think my head just exploded

#### Share this post

##### Share on other sites
Matias Goldberg    9573

To check if your formula is energy conserving, you have to do the integral of your formula just like Fabian Giesen did in this blog (check comments, quick link: http://www.farbrausch.de/~fg/stuff/phong.pdf).

That's a looooot of math and has the risk of making your head explode, but it will make you be 100% sure.

#### Share this post

##### Share on other sites
macnihilist    377

I've been pondering these questions myself and haven't got a satisfactory answer. But so far I can make out 3 general approaches for combining glossy and diffuse parts:

1. Simply add two independent parts and make sure the combined weights are <= 1. Obviously this will not reflect more than comes in if both parts are energy 'conserving' (in the sense that they don't reflect more than comes in...). Whether or not you call that 'physically plausible' is up to you.

2. Scale down diffuse with a factor resembling C*(1-F(N.L))*(1-F(N.V)), where C is some strange normalization constant obtained by doing the corresponding integral (usually with some approximations and worst-case assumptions). This gives a simple layered material, which is symmetric and energy 'conserving'. For example, Ashikhmin-Shirley uses this (although I have no idea how they came up with the strange 1/2s -- probably just empirically). In real-time rendering the 1-F(N.V) is often omitted, which sacrifices symmetry (and some plausibility) for speed.

3. Use a factor C*(1-H(L))*(1-H(V)), where H is the directional hemispherical reflectance of the glossy part. This is slightly nicer than version 2, because it respects all directions in which the glossy part scatters, but you have to know H (approximately). I don't know how plausible the H(V) part is, but at least it keeps things symmetric. A paper that uses this approach is "A Microfacet-based BRDF Generator" by Ashikhmin et al.

Unfortunately no answers to your concrete questions, but maybe it helps a little.

#### Share this post

##### Share on other sites
L. Spiro    25620

Thank you for the replies.

I spoke to a coworker at tri-Ace and it seems Chris_F and I made the same mistake.  The diffuse is not multiplied by (1 - Fresnel), it’s (1 - F0), where F0 is the specular reflectance for the normal direction for the Fresnel, which is Fspec(F0).  We both had assumed that F0 was the Fresnel term and Fspec was the specular color.  At tri-Ace, the specular color is always assumed to be white, and is therefore not present in that equation (or is present only as a magnitude).  It makes more sense now.

When combining the Blinn-Phong specular from that equation with Oren-Nayar, it makes much more sense now to apply (1 - F0) to the diffuse rather than (1 - Fresnel).

L. Spiro

#### Share this post

##### Share on other sites
Matias Goldberg    9573

We both had assumed that F0 was the Fresnel term and Fspec was the specular color.

Somehow I'm not surprised. I'm sick of going through GDC/SIGGRAPH slides and even independent academic papers where they present a formula/equation without (or with incomplete) footnotes that clarifies the meaning of each coefficient and variable. Half of them you have to guess, or dig through all the referenced bibliography to find out.

#### Share this post

##### Share on other sites
Ohforf sake    2052

If you want to check your assumptions, but without computing the integrals by hand, you can always resort to numeric integration using monte carlo sampling. I'm pretty sure, boost comes with a random number generator the produces evenly distributed random directions.

#### Share this post

##### Share on other sites
Bacterius    13165

If you want to check your assumptions, but without computing the integrals by hand, you can always resort to numeric integration using monte carlo sampling. I'm pretty sure, boost comes with a random number generator the produces evenly distributed random directions.

No need for random directions - just use spherical coordinates (and if your BRDF is isotropic, you only need the elevation). Every time you use dot(L, N) in your shader, use cos(theta), and so on. And then you can just integrate it numerically in Mathematica or something.

#### Share this post

##### Share on other sites
InvalidPointer    1842

If you want to check your assumptions, but without computing the integrals by hand, you can always resort to numeric integration using monte carlo sampling. I'm pretty sure, boost comes with a random number generator the produces evenly distributed random directions.

No need for random directions - just use spherical coordinates (and if your BRDF is isotropic, you only need the elevation). Every time you use dot(L, N) in your shader, use cos(theta), and so on. And then you can just integrate it numerically in Mathematica or something.

I don't have a source for this, but I *think* using this approach actually introduces a bias towards the poles. Assuming an unstratified sampling pattern.

#### Share this post

##### Share on other sites
CryZe    773

If you want to check your assumptions, but without computing the integrals by hand, you can always resort to numeric integration using monte carlo sampling. I'm pretty sure, boost comes with a random number generator the produces evenly distributed random directions.

No need for random directions - just use spherical coordinates (and if your BRDF is isotropic, you only need the elevation). Every time you use dot(L, N) in your shader, use cos(theta), and so on. And then you can just integrate it numerically in Mathematica or something.

I don't have a source for this, but I *think* using this approach actually introduces a bias towards the poles. Assuming an unstratified sampling pattern.

If you keep in mind following you can use it without any problem:

[eqn]\int_{\Omega} (\mathrm{n}\cdot \omega) \; \mathrm{d} \omega=\int_\theta \int_\phi cos(\theta)sin(\theta) \; \mathrm{d} \phi \; \mathrm{d} \theta[/eqn]

## 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