DecoColor Shading(const vector3& realIntersectPt, const vector3& norm, DecoLight** lights, INT numLights, const vector3& viewPos, DecoMaterial* mat) { DecoColor col(0, 0, 0); vector3 matDiffuse, matSpecular, matAmbient; vector3 lightPos, lightDiffuse, lightSpecular, lightAmbient; if (mat) { matDiffuse = mat->GetDiffuse(); matSpecular = mat->GetSpecular(); matAmbient = mat->GetAmbient(); } else { matDiffuse = vector3(1, 1, 1); matSpecular = vector3(0, 0, 0); matAmbient = vector3(0.5, 0.5, 0.5); } for (INT i = 0; i < numLights; i++) { lightPos = lights[i]->GetPosition(); lightDiffuse = lights[i]->GetDiffuse(); lightSpecular = lights[i]->GetSpecular(); col += Shading(realIntersectPt, norm, lightPos, viewPos, lightDiffuse, lightSpecular, lightAmbient, matDiffuse, matSpecular, matAmbient); } lightAmbient = vector3(0.5, 0.5, 0.5); col += DecoColor(vector4(lightAmbient.x * matAmbient.x, lightAmbient.y * matAmbient.y, lightAmbient.z * matAmbient.z, 1)); return col; }
void RayTracer::traceRay(Ray *r, int depth, Color* tColor){ if (depth>=m_Depth){ return; } Intersection closest, temp; Material tempM; Color tempColor(0.0,0.0,0.0); Color tempKr(0.0,0.0,0.0); double tempKt=0.0; BRDF closestBRDF; Ray tempRay(glm::dvec3(0), glm::dvec3(0), glm::dvec3(0)); std::vector<Ray*> tempRays; closest = Intersection(glm::dvec3(0), tempM, 100000.0, glm::dvec3(0)); bool foundAny = false; for (unsigned int i = 0; i < myPrims.size(); i++){ if (myPrims[i]->Intersects(r,&temp)){ foundAny = true; if(isCloser(r,temp,closest)){ closest = temp; } } } if(!foundAny){ *tColor += tempColor; return; } // else there is an intersection closestBRDF = closest.GetMaterial().GetBRDF(); // get the BRDF from the closest intersection if (depth == 0){ *tColor += closestBRDF.GetKa(); //add the Ka ambient of material *tColor += closestBRDF.GetKe(); //add the Ke emission of material } // loop through all light sources // for an intersection // cast a shadow ray to all lights at the intersection // & determine if they are visible double shadow =0.0; for (unsigned int i=0; i< myLights.size(); i++){ if (avoidAllLightButKaKe){ continue; } // cast a shadow ray to a light source at the intersection point & put it in tempRay myLights[i]->GenerateLightRays(closest.GetPosition(), &tempRays, closest.GetNormal()); float invSamples = 1.0/tempRays.size(); for(std::vector<Ray*>::iterator it=tempRays.begin(); it!=tempRays.end(); ++it) { // determine if the light is visible foundAny = check4Intersection(*it); if (avoidShadows){ foundAny = false; } if (!foundAny){ shadow=invSamples; // if we didn't find any // do shading calculation for this // light source // Li(Kd max(li*n,0)+Ks(n*hi)^s) stars are dot products // Li = light color // Kd = diffuse // li = light direction // n = surface normal // Ks = specular // hi = half angle vector for the light // s = shininess *tColor += shadow* Shading(myLights[i]->GetColor(),closestBRDF.GetKd(), closestBRDF.GetKs(),(*it)->GetD(), closest.GetNormal(),r->GetD(), closestBRDF.GetS()); } } //shadow = 1 - (shadow / tempRays.size()); shadow=0.0; tempRays.clear(); } // Handle mirror reflections tempKr = closestBRDF.GetKr(); if ( ((tempKr.GetR()>0.0) || (tempKr.GetG()>0.0) || (tempKr.GetB()>0.0)) && avoidReflections == false ) { Ray reflectRay = CreateReflectRay(r->GetD(), closest.GetNormal(), closest.GetPosition()); traceRay(&reflectRay, depth+1, &tempColor); // Make a recursive call to trace the reflected ray tempColor = tempKr*tempColor; *tColor += tempColor; } // Handle refractions tempKt = closestBRDF.GetKt(); if (tempKt>0.0 && avoidRefractions == false){ //std::cout<<tempKt<<std::endl; Ray refractRay = CreateRefractRay(r->GetD(),closest.GetNormal(), closest.GetPosition(),depth); traceRay(&refractRay, depth+1, &tempColor); //recursive call //tempColor *= *tColor += tempColor; } return; }