Tcolor TrayTracer::radianceWithExplicitLight(Tray ray,int reflectLevel) { if(reflectLevel <= 0) return Tcolor(0,0,0); Tcolor finalColor(0,0,0); auto result = scene()->intersect(ray); if (result.geometry()) { auto material = result.geometry ()->material (); if(!material) return finalColor; Tcolor selfColor = material->sampleSelfColor (); //**********Emission. auto emissionColor = selfColor*material->emission (); //reflect Tcolor reflectColor; auto allLights = scene()->getLightList(); for(int i =0;i<allLights.size ();i++) { TexplicitLight * light = allLights[i]; if(!light->isVisible (result.pos (),scene())) continue; //get the irradiance from the explicit light source. auto lightDir = light->getDir (result.pos ()); auto lightRadiance = light->getIrradiance (result.pos (),result.normal (),scene()); reflectColor += lightRadiance * material->BRDF (-ray.direction (),-lightDir,result.normal ()); } //ideal specular radiance from other object. if(material->reflectiveness () > 0) { // get the ideal specular ray. auto reflectVec = reflect(ray.direction (),result.normal ()); auto reflectRay = Tray(result.pos (),reflectVec); auto idealSpecularRadiance = radianceWithExplicitLight(reflectRay,reflectLevel - 1); reflectColor +=idealSpecularRadiance * material->BRDF (-ray.direction (),reflectVec,result.normal ()); } //render euqation. finalColor = emissionColor+ selfColor*reflectColor*material->reflectiveness (); } return finalColor; }
Vector3 RefractiveInterface::shade(const Ray& ray, const HitInfo& hit, const Scene& scene, const bool& isFront) const { Ray rayLight; HitInfo hitLight; Vector3 L = Vector3(0.0f, 0.0f, 0.0f); const Vector3 viewDir = -ray.d; // d is a unit vector const PointLights *plightlist = scene.pointLights(); // loop over all of the POINT lights PointLights::const_iterator plightIter; for (plightIter = plightlist->begin(); plightIter != plightlist->end(); plightIter++) { PointLight* pLight = *plightIter; Vector3 l = pLight->position() - hit.P; rayLight.o = hit.P; rayLight.d = l.normalized(); Vector3 brdf = BRDF(rayLight.d, hit.N, -ray.d, isFront); if (brdf == 0) continue; if (scene.trace(hitLight, rayLight, 0.0001, l.length())) continue; // the inverse-squared falloff float falloff = l.length2(); float nDotL = fabs(dot(hit.N, l)); Vector3 result = pLight->color(); L += nDotL / falloff * pLight->wattage() *brdf * result; } const AreaLights *alightlist = scene.areaLights(); // loop over all of the lights AreaLights::const_iterator alightIter; for (alightIter = alightlist->begin(); alightIter != alightlist->end(); alightIter++) { AreaLight* aLight = *alightIter; vec3pdf vp = aLight->randPt(); Vector3 l = vp.v - hit.P; // shoot a shadow ray to a random point on the area light rayLight.o = hit.P; rayLight.d = l.normalized(); Vector3 brdf = BRDF(rayLight.d, hit.N, -ray.d, isFront); if (brdf == 0) continue; // if the shadow ray hits the "backside of the light" continue to the next area light if (!aLight->intersect(hitLight, rayLight)){ continue; } // if the shadow ray is occluded by another (hence the "skip") object continue the next light if (scene.trace(hitLight, rayLight, aLight, 0.0001, l.length())){ continue; } // the inverse-squared falloff float falloff = l.length2(); float nDotL = fabs(dot(hit.N, l)); Vector3 result = aLight->color(); L += std::max(0.0f, dot(hitLight.N, -l))* 0.0f, nDotL / falloff* aLight->wattage() / aLight->area() *brdf * result / (vp.p); } // add the ambient component L += m_ka; return L; }
Tcolor TrayTracer::radiancePathTracer(Tray ray, int reflectLevel) { if(reflectLevel <=0) return Tcolor(0,0,0); auto result = scene()->intersect(ray); if (result.geometry()) { auto material = result.geometry ()->material (); auto emissionColor = material->sampleSelfColor () * material->emission (); auto reflectColor = Tcolor(0,0,0); switch(material->getType ()) { case Tmaterial::MaterialType::Mirror://ideal specular object. { auto reflectVec = reflect(ray.direction (),result.normal ()); auto reflectRay = Tray(result.pos (),reflectVec); auto idealSpecularRadiance = radiancePathTracer(reflectRay,reflectLevel - 1); reflectColor +=idealSpecularRadiance * material->BRDF (-ray.direction (),reflectVec,result.normal ()); } break; case Tmaterial::MaterialType::Light://ideal emission object. { reflectColor = Tcolor(0,0,0); } break; case Tmaterial::MaterialType::BlinnPhong: { } break; case Tmaterial::MaterialType::Diffuse: { Tvector nl; if(Tvector::dotProduct (result.normal (),ray.direction ())<0) { nl = result.normal (); }else { nl = result.normal ().negatived(); } double r1=2*TbaseMath::PI*TbaseMath::randF (); double r2=TbaseMath::randF (); double r2s=sqrt(r2); Tvector w=nl; Tvector u; if(fabs(w.x())>0.1) { u = Tvector(0,1,0); }else { u = Tvector(1,0,0); } u = Tvector::crossProduct (u,w); u.normalize (); Tvector v=Tvector::crossProduct (w,u); Tvector dir = (u*cos(r1)*r2s + v*sin(r1)*r2s + w*sqrt(1-r2)).normalized(); reflectColor = radiancePathTracer(Tray(result.pos (),dir),reflectLevel - 1); } break; } return emissionColor + material->selfColor () * reflectColor * material->reflectiveness (); } return Tcolor(0,0,0); }