bool TdirectionalLight::isVisible(Tvector pos,Tscene * scene) { auto shadowRay = Tray(pos,-m_dir); auto result = scene->intersect (shadowRay); if(result.geometry ()) { return false; }else { return true; } }
bool Tsphere::isVisible(Tvector pos, Tscene *scene) { auto dir = m_center - pos; dir.normalize (); auto result = scene->intersect (Tray(pos,dir)); if(result.geometry () == this) { return true; }else { return false; } }
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; }
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); }