Metal shader correct ?

Started by
5 comments, last by Chris_F 10 years, 11 months ago

Hey guys, I've been trying to implement a phsically based metal kind of shader and I was wondering if what I'm doing is correct.

Have a look at my shader:


	// Compute half-way-vector
	float3 H = (V + L);
	H = normalize(H); // normalize

	// Specular Fresnel Term approximation by Schlick
	float LdotH = saturate(dot(L, H));
	float3 Fresnel_spec_multiplier = 1.0f - FresnelReflectance;
	float3 Fresnel_spec = FresnelReflectance + exp2(log2(1.0f - LdotH) * 5 + log2(Fresnel_spec_multiplier));

	// Normalized Blinn-Phong NDF (D)
	float D = 0.0f;
	float NdotH = saturate(dot(N, H));
	float NormalizationFactor = ((glossiness + 2) / 2);
	D = exp2(log2(NdotH) * glossiness + log2(NormalizationFactor)); // NormalizationFactor * pow(NdotH, glossiness)

	// Cook-Torrance geometry term approximation by Kelemen & Szirmay-Kalos
	float G = 1.0f / (LdotH * LdotH + 0.0000001f);

	// Microfacet BRDF f(l,v)
	float3 f_microfacet = (Fresnel_spec * G * D) / 4.0f;

	Radiance += f_microfacet * Li * Cosine;	
	Radiance += ReflectionColor * Fresnel_spec;	

As you can see I'm already using a custom microfacet brdf using an approximation of the cook-torrance geometry term and the fresnel factor but for the NDF just a regular blinn-phong model. Is the cook-torrance NDF actually the beckmann distribution function or is it something different ? If yes then should I rather use a precomputed distribution texture for this like it's found on here: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch14.html ?

I've found this code segment for the cook-torrance NDF on pixars renderman page:


float alpha = acos(NdotH);
float D = gaussConstant*exp(-(alpha*alpha)/(m*m));

alpha in this case would be NdotH and m is the microfacet H ? And the guassian constant would be something like 0.8346...? (according to what I found on wikipedia).

This is a screenshot of how it looks using fresnel of gold:

http://d.pr/i/mOBL

here's another one using a different normal map:

http://d.pr/i/xwz7

I think it's wrong to tint the environment color with the specular fresnel again after I've multiplied it before by the fresnel using NdotV ?

It's just that it looks very "blueish" to me if I don't do that, have a look:

http://d.pr/i/RiCt

Advertisement

You could just tint the environment color. There isn't much of an issue with that.

You shouldn't be multiplying your environment map with Fresnel_spec, which uses the half vector.

I would not recommend Gaussian distribution function, or Beckmann, or texture look-ups. GGX is about as cheap as Blinn-Phong to compute, and supports very rough surfaces like Beckmann. Out of all of them I think it looks the best too.

As for your gold looking "blueish", of course it does. It's in a blue environment. If everything around it is blue, then what else is there to reflect but blue?

Well yeah...was just not sure if it would be this strong of a blue tone since gold would be kind of yellowish I guess :p (the specular itself is more so, so I guess its okay...)

I removed the multiplication, I realized it was wrong since I was multiplying it two times in a row with the fresnel term.

About the GGX, do you have a sample code / paper on how to implement that ?

Well yeah...was just not sure if it would be this strong of a blue tone since gold would be kind of yellowish I guess tongue.png (the specular itself is more so, so I guess its okay...)

I removed the multiplication, I realized it was wrong since I was multiplying it two times in a row with the fresnel term.

About the GGX, do you have a sample code / paper on how to implement that ?

[attachment=15442:eqn3a.png]


float NdotH_2 = NdotH * NdotH;

float a_2 = a * a;

float D = a_2 / pow(NdotH_2 * (a_2 - 1.0) + 1.0, 2.0);

Thanks a lot. Is the roughness input value range similar to blinn-phong ? Meaning 0-2048 (low to high gloss)

Thanks a lot. Is the roughness input value range similar to blinn-phong ? Meaning 0-2048 (low to high gloss)

No, it's similar to Beckmann (0, +inf], but you will probably stick to values in the range of 0-1 for most common materials.

This topic is closed to new replies.

Advertisement