Thank you, my Cook Torrance one is more complex, but when I use that, I’m not clear on what I’m doing with the end result. I end up with a diffuse output and a specular output but I’m unclear on whether those are multipliers for the base color, or should be summed with it, or just summed themselves. If I multiply with base color or use them as-is, my model renders as almost completely black with a few specular highlights - and I’m not sure how that would be different when using a reflection map because my returns from Cook Torrance are still going to be mostly black, so if I multiply any color by it, it’ll end up as black. If I add to the base color, I get some reflection but it looks more like plastic than anything else. I was reading that the black parts should be reflection, but I don’t know how that would work unless it were just summed up with a reflection map or perhaps multiplied by the negative such that the white parts ended up white and the black parts ended up showing the reflection.
This is my cook torrance function which I lifted from kosmonaut’s DeferredEngine project:
float3 SpecularCookTorrance(float NdotL, float3 normal, float3 negativeLightDirection, float3 cameraDirectionP, float diffuseIntensity, float3 diffuseColor, float f0, float roughness)
{
float3 specular = float3(0, 0, 0);
[branch]
if (NdotL > 0.0f)
{
float3 halfVector = normalize(negativeLightDirection + cameraDirectionP);
float NdotH = saturate(dot(normal, halfVector));
float NdotV = saturate(dot(normal, cameraDirectionP));
float VdotH = saturate(dot(cameraDirectionP, halfVector));
float mSquared = roughness * roughness;
//Trowbridge-Reitz
float D_lowerTerm = (NdotH * NdotH * (mSquared * mSquared - 1) + 1);
float D = mSquared * mSquared / (3.14 * D_lowerTerm * D_lowerTerm);
//fresnel (Schlick)
float F = pow(1.0 - VdotH, 5.0);
F *= (1.0 - f0);
F += f0;
//Schlick Smith
float k = (roughness + 1) * (roughness + 1) / 8;
float g_v = NdotV / (NdotV * (1 - k) + k);
float g_l = NdotL / (NdotL * (1 - k) + k);
float G = g_l * g_v;
specular = max(0, (D * F * G) / (4 * NdotV * NdotL)) * diffuseIntensity * diffuseColor * NdotL;
}
return specular;
}
I’m confused about why he has negativeLightDirection
in there. When I’m reading up on cook torrance in other shaders, they typically seem to ask for just a regular light direction. So I don’t know if I should be flipping the sign on the lightdir or not when I pass it in.
Also for diffuseColor, I’m passing in the base color of the texture. Maybe that is supposed to just be diffuse light color.
This is my f0:
float f0 = lerp(0.04f, baseColor.rgb, metalness);