I am having troubles making a BRDF that has both specular and diffuse part. Each one is weighted by a coefficient and the sum of coefficients should be equal to one.
I want this layered BRDF to be the simplest possible and physically right.
What I am doing for the moment is:
Vector3f sampleBRDF(Vector3f& wi) {
float randomNumber = generateUniform();
if (randomNumber < 0.5f) {
// We will create a specular ray
return reflectZUp(wi);
}
else {
// We will create a diffuse ray
float phi = 2_PI * generateUniform();
float cosTheta = sqrt(generateUniform());
float theta = acos(cosTheta);
Vector3f wo = toCarthesian(Vector2f(phi, theta));
wo.z = isSameHemisphereZUp(wi, wo) ? wo.z : -wo.z;
return wo;
}
}
float brdf(Vector3f& wi, Vector3f& wo, float diffuseProbability) {
if (isSpecular(wi, wo))
return 2.f * (1.f - diffuseProbability);
else
return 2.f * abs(wo.z) / PI;
}
float pdf(wi, wo) {
if (isSpecular(wi, wo))
return (1.f - diffuseProbability);
else
return diffuseProbability * abs(wo.z) / PI;
}
I am pretty sure my sampling method is right, because it is a very common one. But there may have mistakes in my BRDF et and PDF methods. The results that I obtain from this BRDF don't satisfy me.
If you have any ideas, advices or questions, I would be happy to read/answer you !
Have a good day.