I have a scene looking like this: enter image description here
But I can't seem to wrap my head around how to keep the reflections from being brighter than the real object.
Vec3f fireRaysRec(Ray& ray, unsigned int recdepth, unsigned int& iTests) {
Vec3f retcolor;
HitRec hitRec;
retcolor.set(0.0f, 0.0f, 0.0f);
hitRec.tHit = Ray::tMax;
hitRec.anyHit = false;
hitRec.primIndex = -1;
if(recdepth <= recursionMaxDepth_UI) {
searchClosestHit(ray, hitRec, iTests);
if(hitRec.anyHit) {
retcolor = scene->objects_VPP[hitRec.primIndex]->getMaterialAmbient(); //Apply material ambient
//Lighting (Phong)
for(int i = 0; i < (int)scene->lights_VPL.size(); ++i) {
if(!fireShadowRay(hitRec, scene->lights_VPL[i], iTests)) { //Check if NOT in shadow from light #i
//Calculate lighting/color (phong)
//Vectors needed: to light (L), to viewer/camera (V), normal (n), reflector (R)
//matAmb*lightAmb + matDiff*lightDiff*(N.L) + matSpec*lightSpec*(R.V)^shine
//R = 2(l . n)n - l
float dotnl, dotrv, dotln;
Vec3f L, V, N, R;
N = hitRec.n;
V = (-ray.d).normalize();
//retcolor = retcolor.multCoordwise(scene->lights_VPL[i].getAmbientLight());
L = (scene->lights_VPL[i].getPosition() - hitRec.p).normalize();
dotln = L.dot(N);
if(dotln < 0.0f) { dotln = 0.0f; }
R = ((N * (2 * dotln)) - L).normalize(); //R = (2 * L.dot(N) * N - L)
dotnl = N.dot(L);
if(dotnl < 0.0f) { dotnl = 0.0f; }
dotrv = R.dot(V);
if(dotrv < 0.0f) { dotrv = 0.0f; }
//retcolor += scene->objects_VPP[hitRec.primIndex]->getMaterialAmbient().multCoordwise(scene->lights_VPL[i].getAmbientLight());
if(scene->objects_VPP[hitRec.primIndex]->getTexture() == NULL) {
retcolor += (scene->objects_VPP[hitRec.primIndex]->getMaterialDiffuse().multCoordwise(scene->lights_VPL[i].getDiffuseLight()) * dotnl);
}
else {
Vec2i texcoords = scene->objects_VPP[hitRec.primIndex]->calculateTexCoords(hitRec);
Vec3f texcol = scene->objects_VPP[hitRec.primIndex]->getTexture()->getPixel(texcoords.getX(), texcoords.getY());
//std::cout << "TexCol: " << texcol.r << ", " << texcol.g << ", " << texcol.b << std::endl;
retcolor += (texcol.multCoordwise(scene->lights_VPL[i].getDiffuseLight()) * dotnl);
}
retcolor += (scene->objects_VPP[hitRec.primIndex]->getMaterialSpecular().multCoordwise(scene->lights_VPL[i].getSpecularLight()) * pow(dotrv, scene->objects_VPP[hitRec.primIndex]->getMaterialShininess()));
}
else { } //In shadow from light #i - dont apply light from light #i
}
//Reflection
if(scene->objects_VPP[hitRec.primIndex]->getMaterialReflective()) {
//Vectors needed: to camera/viewer (V), normal (N), reflector (R)
//R = 2(v . n)n - v
float dotvn;
Vec3f reflectioncolor;
Vec3f V, N, R;
Ray refray;
V = (-ray.d).normalize();
N = hitRec.n;
dotvn = V.dot(N);
if(dotvn < 0.0f) { dotvn = 0.0f; }
R = (N * (2 * dotvn) - V).normalize(); //R = (2 * (-ray.d.dot(hitRec.n));
refray.o = (hitRec.p + (hitRec.n * 0.01f)); //Move out along the normal a little bit to avoid self-hit
refray.d = R;
reflectioncolor = (fireRaysRec(refray, (recdepth + 1), iTests) * scene->objects_VPP[hitRec.primIndex]->getMaterialReflection());
retcolor += (scene->objects_VPP[hitRec.primIndex]->getMaterialSpecular().multCoordwise(reflectioncolor));
}
//Clamping
if(retcolor.r < 0.0f) { retcolor.r = 0.0f; } if(retcolor.r > 1.0f) { /*retcolor.r = 1.0f; std::cout << "OVER 1 R!" << std::endl;*/ }
if(retcolor.g < 0.0f) { retcolor.g = 0.0f; } if(retcolor.g > 1.0f) { /*retcolor.g = 1.0f; std::cout << "OVER 1 G!" << std::endl;*/ }
if(retcolor.b < 0.0f) { retcolor.b = 0.0f; } if(retcolor.b > 1.0f) { /*retcolor.b = 1.0f; std::cout << "OVER 1 B!" << std::endl;*/ }
}
}
return retcolor;
}
Any help would be greatly appriciated.
Aucun commentaire:
Enregistrer un commentaire