Oren-Nayar with Blinn-Phong Specular

Started by
8 comments, last by CryZe 11 years ago

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

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Advertisement

I think my head just exploded

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.

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

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

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

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.

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.

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.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

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.

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.

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]

This topic is closed to new replies.

Advertisement