Now I'm working on a basic CG program about the BRDF. And after I got the image, it seems that, all the points face to the light is too bright, I don't know the reason. And here's my code, where I tried to invoke the lookup_brdf_val function.
Vec3f hitNormal = ray.hit->getNormal(ray);
if(hitNormal * ray.dir > 0)
hitNormal = -hitNormal;
result = Vec3f(0, 0, 0);
Ray lightRay;
lightRay.org = ray.org + ray.dir * ray.t;
Vec3f intensity;
for(unsigned int l = 0; l < scene->lights.size(); l++)
{
scene->lights[l]->illuminate(lightRay, intensity);
if(!scene->isOccluded(lightRay))
{
double theta1,theta2;
// Calculate the theta1 and theta2.
theta1 = acosf(-(ray.dir * hitNormal));
theta2 = acosf(lightRay.dir * hitNormal);
// Calculate the fi1 and fi2.
double fi1 = 0;
Vec3f O = ray.org + ray.dir * ray.t;
Vec3f A = O - ray.dir;
Vec3f C = (ray.dir * hitNormal) * hitNormal + A;
Vec3f B = lightRay.dir + O;
Vec3f D = ((-lightRay.dir) * hitNormal) * hitNormal + B;
Vec3f OC = C - O;
Vec3f OD = D - O;
double fi2 = acosf((OD * OC) / (length(OD) * length(OC)));
double x = 0;
double y = 0;
double z = 0;
double &r = x;
double &g = y;
double &b = z;
read->lookup_brdf_val(theta1, fi1, theta2, fi2, r, g, b);
result += Vec3f(r * scale.x * intensity.x, g * scale.y * intensity.y, b * scale.z * intensity.z);
I suggest start from a simpler BRDF to make sure that your main loop is not broken -- try something simple like lambert:
max(0,dot(lightRay,hitNormal))
and be sure that those are normalized vectors. Divide byscene->lights.size()
if it's simply too bright because you have too many lights.If the image looks correct with a simple BRDF, now just try it with variations of your other components. You don't give the code for
lookup_brdf_val()
at all, so beyond that one can only speculate.It's just like any other programming, though. Reduce the # of variables until you find the one that's awry.