That's why I was hoping someone can point out what I'm doing wrong or what I'm missing.

-> see below

**Edited by lipsryme, 03 November 2012 - 01:05 PM.**

5 replies to this topic

Posted 22 October 2012 - 12:16 PM

I'm trying to implement a microfacet brdf but my results are wrong somehow.

That's why I was hoping someone can point out what I'm doing wrong or what I'm missing.

-> see below

That's why I was hoping someone can point out what I'm doing wrong or what I'm missing.

-> see below

**Edited by lipsryme, 03 November 2012 - 01:05 PM.**

Portfolio/Blog: http://marcel-schindler.weebly.com

Sponsor:

Posted 03 November 2012 - 12:16 PM

Actually doing it like that makes it not work at all.

My View direction is being calculated like this:

Have to say I got it working now with a phong distribution but anything else (the commented out part) gives me wrong results.

Beckmann or Trowbridge-Reitz doesn't...

My View direction is being calculated like this:

// Calculate Position from linear view space depth float3 ViewRay = input.PositionVS.xyz; float depth = DepthTarget.Sample(PointSampler, input.UV).r; float3 ViewDir = ViewRay * depth; // subtraction by the cam position not needed since we're already in view space

Have to say I got it working now with a phong distribution but anything else (the commented out part) gives me wrong results.

// Compute Fresnel Term (F) using Schlick's approximation float LdotH = max(0, dot(-L, H)); float base = 1 - LdotH; float exponent = pow(base, 5.0f); float3 F = saturate(SpecularAlbedo + (1 - SpecularAlbedo) * exponent); // Lambert float3 kd = NdotL; Lr.rgb += (kd / PI) * Ei; // Normalized Blinn-Phong distribution (D) float D = 0.0f; float NdotH = max(0, dot(N, H)); D = ((SpecularPower + 2) / 2 * PI) * pow(NdotH, SpecularPower); // Beckmann distribution (D) //float NdotH = max(0, dot(N, H)); //float NdotH2 = NdotH * NdotH; //float NdotH4 = NdotH * NdotH * NdotH * NdotH; //float SpecularPower2 = SpecularPower * SpecularPower; //float Beckmann_exponent = -((1 - NdotH2) / (SpecularPower2 * NdotH2)); //float D = 1 * exp(Beckmann_exponent) / PI * SpecularPower2 * NdotH4; // Trowbridge-Reitz (GGX) distribution //float NdotH = max(0, dot(N, H)); //float SpecPow2 = SpecularPower * SpecularPower; //float D = SpecPow2 / PI * pow(((NdotH*NdotH) * (SpecPow2 - 1) + 1), 2); // Cook-Torrance approximation (G) float NdotV = max(0, dot(N, V)); float G = 1.0f; float3 nominator = F * G * D; float denominator = 4 * ((LdotH+0.000001f) * (LdotH+0.000001f)); Ls.rgb += nominator / denominator;

Beckmann or Trowbridge-Reitz doesn't...

**Edited by lipsryme, 03 November 2012 - 01:06 PM.**

Portfolio/Blog: http://marcel-schindler.weebly.com

Posted 03 November 2012 - 08:27 PM

Pretty sure the Beckmann distribution is actually this (and same comment for GGX, I would guess):

This is my path tracer code for Beckmann, it uses a raw BRDF so you'll have to modify the inputs (the incident vector goes towards the surface, the exitant vector goes away from it). The vector * vector operation is the dot product. Also I'm not using the tangent formula trick yet whereas you seem to be.. sorry:

http://pastebin.com/pHqCH1dc

Might have gone overboard with the absolute values but I was dealing with refraction at the same time and didn't want to take risks

EDIT: dammit, why are the code tags munching my newlines?

EDIT: pastebin it is!

float D = 1 * exp(Beckmann_exponent) / (PI * SpecularPower2 * NdotH4);

This is my path tracer code for Beckmann, it uses a raw BRDF so you'll have to modify the inputs (the incident vector goes towards the surface, the exitant vector goes away from it). The vector * vector operation is the dot product. Also I'm not using the tangent formula trick yet whereas you seem to be.. sorry:

http://pastebin.com/pHqCH1dc

Might have gone overboard with the absolute values but I was dealing with refraction at the same time and didn't want to take risks

EDIT: dammit, why are the code tags munching my newlines?

EDIT: pastebin it is!

**Edited by Bacterius, 03 November 2012 - 08:39 PM.**

The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

- *Pessimal Algorithms and Simplexity Analysis*

Posted 04 November 2012 - 05:01 PM

Your GGX distribution is missing a parenthesis. Everything should be in the denominator except the alpha^2. So the correct implementation would be:

float NdotH = max(0, dot(N, H));

float SpecPow2 = SpecularPower * SpecularPower;

float D = SpecPow2 / (PI * pow(((NdotH*NdotH) * (SpecPow2 - 1) + 1), 2));

Don't do it this way, you are wasting instructions this way. Do it like that:

float G = min(1, 2 * NdH / VdH * min(NdV, NdL));

float NdotH = max(0, dot(N, H));

float SpecPow2 = SpecularPower * SpecularPower;

float D = SpecPow2 / (PI * pow(((NdotH*NdotH) * (SpecPow2 - 1) + 1), 2));

float G = min(1, min(2 * NdH * NdV / VdH, 2 * NdH * NdL / VdH));

Don't do it this way, you are wasting instructions this way. Do it like that:

float G = min(1, 2 * NdH / VdH * min(NdV, NdL));

Posted 05 November 2012 - 07:31 AM

I'm still getting crazy high values (basically the entire mesh white). Does the input alpha have to be ridiculously high ?

edit: hmm no higher values don't seem to fix this.

edit2: ok so when only outputting D or D*F it looks more like it should (still very bright). Is there something wrong with my Geometry term ?

edit: hmm no higher values don't seem to fix this.

edit2: ok so when only outputting D or D*F it looks more like it should (still very bright). Is there something wrong with my Geometry term ?

**Edited by lipsryme, 05 November 2012 - 09:02 AM.**

Portfolio/Blog: http://marcel-schindler.weebly.com