• Create Account

### #ActualCryZe

Posted 04 February 2013 - 06:36 AM

float geo_a = (2.0 * NdotH * NdotV) / VdotH;
float geo_b = (2.0 * NdotH * NdotL) / VdotH;
float G = min(1.0, max(0, min(geo_a, geo_b)));

You can improve this part of the code this way:
float g_min = min(NdotV, NdotL);
float G = saturate(2 * NdotH * g_min / VdotH);
Also, don't ever use max(0, dot(a, b)). Instead use saturate(dot(a, b)) which compiles into a single instruction.

Isn't real-time graphics programming all about approximations?

It is, but is using the complement of Fspecular actually a good one? I don't think so (unless you're using Fdiffuse).

I think someone should approximate a diffuse BRDF using the equation I posted in my post above. That would be a way better approximation.

To get back to the original topic:

The last one is the correct Cook-Torrance microfacet model. Sometimes you find (ns + 2) / (2 * pi) or (ns + 2) / (8 * pi) as the normalization factor for Blinn-Phong. The second one is already pre-multiplied with the 1/4 while the first one is the distribution function for the microfacet model.

And this one is the correct Beckmann NDF:

I wouldn't recommend the Beckmann NDF though. It's pretty damn slow in comparison to other NDFs because of 2 reciprocals and the exponential function. (Y u no use GGX xD)

This is the BRDF I'm using:

I'm using GGX as the distribution function, Schlick's approximation of fresnel as fresnel term and Walter's geometric term for the GGX distribution function.

I color-coded everything for implementation details. The grey parts are just parts of the BRDF and don't need to be implemented. The green parts can be calculated once for every pixel. And the red parts are the only parts, that actually need to be calculated for every light.

### #10CryZe

Posted 04 February 2013 - 06:17 AM

float geo_a = (2.0 * NdotH * NdotV) / VdotH;
float geo_b = (2.0 * NdotH * NdotL) / VdotH;
float G = min(1.0, max(0, min(geo_a, geo_b)));

You can improve this part of the code this way:
float g_min = min(NdotV, NdotL);
float G = saturate(2 * NdotH * g_min / VdotH);
Also, don't ever use max(0, dot(a, b)). Instead use saturate(dot(a, b)) which compiles into a single instruction.

Isn't real-time graphics programming all about approximations?

It is, but is using the complement of Fspecular actually a good one? I don't think so (unless you're using Fdiffuse).

I think someone should approximate a diffuse BRDF using the equation I posted in my post above. That would be a way better approximation.

To get back to the original topic:

The last one is the correct Cook-Torrance microfacet model. Sometimes you find (ns + 2) / (2 * pi) or (ns + 2) / (8 * pi) as the normalization factor for Blinn-Phong. The second one is already pre-multiplied with the 1/4 while the first one is the distribution function for the microfacet model.

And this one is the correct Beckmann NDF:

I wouldn't recommend the Beckmann NDF though. It's pretty damn slow in comparison to other NDFs because of 2 reciprocals and the exponential function. (Y u no use GGX xD)

This is the BRDF I'm using:

I'm using GGX as the distribution function, Schlick's approximation of fresnel as fresnel term and Walter's geometric term for the GGX distribution function.

### #9CryZe

Posted 04 February 2013 - 06:10 AM

float geo_a = (2.0 * NdotH * NdotV) / VdotH;
float geo_b = (2.0 * NdotH * NdotL) / VdotH;
float G = min(1.0, max(0, min(geo_a, geo_b)));

You can improve this part of the code this way:
float g_min = min(NdotV, NdotL);
float G = saturate(2 * NdotH * g_min / VdotH);
Also, don't ever use max(0, dot(a, b)). Instead use saturate(dot(a, b)) which compiles into a single instruction.

Isn't real-time graphics programming all about approximations?

It is, but is using the complement of Fspecular actually a good one? I don't think so (unless you're using Fdiffuse).

I think someone should approximate a diffuse BRDF using the equation I posted in my post above. That would be a way better approximation.

To get back to the original topic:

The last one is the correct Cook-Torrance microfacet model. Sometimes you find (ns + 2) / (2 * pi) or (ns + 2) / (8 * pi) as the normalization factor for Blinn-Phong. The second one is already pre-multiplied with the 1/4 while the first one is the distribution function for the microfacet model.

And this one is the correct Beckmann NDF:

I wouldn't recommend the Beckmann NDF though. It's pretty damn slow in comparison to other NDFs because of 2 reciprocals and the exponential function. (Y u no use GGX xD)

### #8CryZe

Posted 04 February 2013 - 06:08 AM

float geo_a = (2.0 * NdotH * NdotV) / VdotH;
float geo_b = (2.0 * NdotH * NdotL) / VdotH;
float G = min(1.0, max(0, min(geo_a, geo_b)));

You can improve this part of the code this way:
float g_min = min(NdotV, NdotL);
float G = saturate(2 * NdotH * g_min / VdotH);
Also, don't ever use max(0, dot(a, b)). Instead use saturate(dot(a, b)) which compiles into a single instruction.

Isn't real-time graphics programming all about approximations?

It is, but is using the complement of Fspecular actually a good one? I don't think so (unless you're using Fdiffuse).

I think someone should approximate a diffuse BRDF using the equation I posted in my post above. That would be a way better approximation.

To get back to the original topic:

The last one is the correct Cook-Torrance microfacet model. Sometimes you find (ns + 2) / (2 * pi) or (ns + 2) / (8 * pi) as the normalization factor for Blinn-Phong. The second one is already pre-multiplied with the 1/4 while the first one is the distribution function for the microfacet model.

And this one is the correct Beckmann NDF:

I wouldn't recommend the Beckmann NDF though. It's pretty damn slow in comparison to other NDFs because of 2 reciprocals and the exponential function. (Y u no use GGX xD)

### #7CryZe

Posted 04 February 2013 - 06:08 AM

float geo_a = (2.0 * NdotH * NdotV) / VdotH;
float geo_b = (2.0 * NdotH * NdotL) / VdotH;
float G = min(1.0, max(0, min(geo_a, geo_b)));

You can improve this part of the code this way:
float g_min = min(NdotV, NdotL);float G = saturate(2 * NdotH * g_min / VdotH);
Also, don't ever use max(0, dot(a, b)). Instead use saturate(dot(a, b)) which compiles into a single instruction.

Isn't real-time graphics programming all about approximations?

It is, but is using the complement of Fspecular actually a good one? I don't think so (unless you're using Fdiffuse).

I think someone should approximate a diffuse BRDF using the equation I posted in my post above. That would be a way better approximation.

To get back to the original topic:

The last one is the correct Cook-Torrance microfacet model. Sometimes you find (ns + 2) / (2 * pi) or (ns + 2) / (8 * pi) as the normalization factor for Blinn-Phong. The second one is already pre-multiplied with the 1/4 while the first one is the distribution function for the microfacet model.

And this one is the correct Beckmann NDF:

I wouldn't recommend the Beckmann NDF though. It's pretty damn slow in comparison to other NDFs because of 2 reciprocals and the exponential function. (Y u no use GGX xD)

### #6CryZe

Posted 04 February 2013 - 06:06 AM

float geo_a = (2.0 * NdotH * NdotV) / VdotH;
float geo_b = (2.0 * NdotH * NdotL) / VdotH;
float G = min(1.0, max(0, min(geo_a, geo_b)));

You can improve this part of the code this way:
float g_min = min(NdotV, NdotL);
float G = saturate(2 * NdotH * g_min / VdotH);
Also, don't ever use max(0, dot(a, b)). Instead use saturate(dot(a, b)) which compiles into a single instruction.

Isn't real-time graphics programming all about approximations?

It is, but is using the complement of Fspecular actually a good one? I don't think so (unless you're using Fdiffuse).

I think someone should approximate a diffuse BRDF using the equation I posted in my post above. That would be a way better approximation.

To get back to the original topic:

This one is the correct Cook-Torrance microfacet model.

And this one is the correct Beckmann NDF:

I wouldn't recommend the Beckmann NDF though. It's pretty damn slow in comparison to other NDFs because of 2 reciprocals and the exponential function. (Y u no use GGX xD)

PARTNERS