bool MaterialBasicRefractive::OutputRay( const Ray& incident, DifferentialGeometry* dg, RandomDeviate& rand, Ray* outputRay ) const { double randomNumber = rand.RandomDouble(); if( dg->shapeFrontSide ) { if ( randomNumber < reflectivityFront.getValue() ) { *outputRay = *ReflectedRay( incident, dg, rand ); return true; } else if ( randomNumber < ( reflectivityFront.getValue() + transmissivityFront.getValue() ) ) { *outputRay = *RefractedtRay( incident, dg, rand ); return true; } else return false; } else { if ( randomNumber < reflectivityBack.getValue() ) { *outputRay = *ReflectedRay( incident, dg, rand ); return true; } else if ( randomNumber < ( reflectivityBack.getValue() + transmissivityBack.getValue() ) ) { *outputRay = *RefractedtRay( incident, dg, rand ); return true; } else return false; } }
Color Raytracer::IndirectLighting(const Ray & aIncidentRay, const Intersection& aIntersection, int aDepth) { int SecondaryRays = 1; Color AccumulatedColor; //Create 2 vectors orthonormal to the intersection normal and to each other vec3 rand = vec3(Utils::RandNormal(), Utils::RandNormal(), Utils::RandNormal()); vec3 U = normalize(cross(aIntersection.Local.Normal, rand)); vec3 V = normalize(cross(U, aIntersection.Local.Normal)); for (int i = 0; i < SecondaryRays; i++) { vec3 Alpha = Utils::RandNormal() * U; vec3 Beta = Utils::RandNormal() * V; Ray ReflectedRay(aIntersection.Local.Pos, normalize(aIntersection.Local.Normal + Alpha + Beta)); Color TempColor; Trace(ReflectedRay, &TempColor, aDepth + 1); AccumulatedColor += TempColor; } return AccumulatedColor / SecondaryRays; }
bool MaterialAngleDependentRefractive::OutputRay( const Ray& incident, DifferentialGeometry* dg, RandomDeviate& rand, Ray* outputRay ) const { NormalVector dgNormal; if( dg->shapeFrontSide ) dgNormal = dg->normal; else dgNormal = - dg->normal; double incidenceAngle = acos( DotProduct( -incident.direction(), dgNormal ) ); std::vector< double> reflectivityTransmissivity = OutputPropertyValue( m_frontReflectivityIncidenceAngle, m_frontReflectivityValue, m_frontTransmissivityValue, incidenceAngle ); double reflectivity = reflectivityTransmissivity[0]; double transmissivity = reflectivityTransmissivity[1]; double randomNumber = rand.RandomDouble(); if( dg->shapeFrontSide ) { if ( randomNumber < reflectivity ) { *outputRay = *ReflectedRay( incident, dg, rand ); return true; } else if ( randomNumber < ( reflectivity + transmissivity ) ) { *outputRay = *RefractedtRay( incident, dg, rand ); return true; } else return false; } else { if ( randomNumber < reflectivity ) { *outputRay = *ReflectedRay( incident, dg, rand ); return true; } else if ( randomNumber < ( reflectivity + transmissivity ) ) { *outputRay = *RefractedtRay( incident, dg, rand ); return true; } else return false; } }
void Raytracer::Trace(const Ray& aRay, Color* aColor, int aDepth) { aq_float T; Intersection RayIntersection; if (!mScene->Intersect(aRay, &T, &RayIntersection)) { *aColor = mScene->Properties.BackgroundColor; return; } *aColor = COLOR::BLACK; for (Light* light : mScene->GetLights()) { *aColor += Shade(aRay, RayIntersection, *light); } *aColor = clamp(*aColor, 0.0, 100.0); //Russian roulette for stopping recursive if (aDepth > mScene->Properties.RecursiveDepth) { aq_float AvgReflectance = sum(RayIntersection.Mat.kr) / 3; if (AvgReflectance < Utils::RandFloatInterval(0.0, 1.2)) { return; } } //Ambient occlusion //*aColor += 0.2 * IndirectLighting(aRay, RayIntersection, aDepth); //Reflection if (sum(RayIntersection.Mat.kr) > 0) { Ray ReflectedRay(RayIntersection.Local.Pos, reflect(aRay.Dir, RayIntersection.Local.Normal)); Color ReflectedColor; Trace(ReflectedRay, &ReflectedColor, aDepth + 1); *aColor = mix(*aColor, ReflectedColor, RayIntersection.Mat.kr); } ////Refraction if (RayIntersection.Mat.Transparency > 0) { Ray RefractedRay(RayIntersection.Local.Pos, refract(aRay.Dir, RayIntersection.Local.Normal, RayIntersection.Mat.RefractiveIndex)); Color RefractedColor; Trace(RefractedRay, &RefractedColor, aDepth + 1); *aColor = mix(*aColor, RefractedColor, RayIntersection.Mat.Transparency); } }