bool RayBouncer::ReflectionBounce( RayBounce& raybounce, const Ray& ray, const Scene& scene, const RayShader& shader, const PrimitiveHit& primitivehit, const real& ior1, const real& ior2, std::size_t depth ) const { raybounce.ray = ray; const Primitive& primitive = primitivehit.first; const PrecalculatedMaterial& material = primitivehit.second; const Hit& hit = primitivehit.third; bool hasreflectivity = std::any_of( material.reflectivity.begin( ), material.reflectivity.end( ), real_compare<std::greater<>, 0>( ) ); if ( !hasreflectivity ) return false; vec3 reflectionraydir = reflect( ray.direction, hit.normal ); Ray reflectionray( hit.contact + reflectionraydir * scene.Bias(), reflectionraydir ); Bounce( raybounce, reflectionray, scene, shader, primitivehit, depth + 1 ); return true; }
bool RayBouncer::RefractionBounce( RayBounce& raybounce, const Ray& ray, const Scene& scene, const RayShader& shader, const PrimitiveHit& primitivehit, const real& ior1, const real& ior2, std::size_t depth ) const { const Primitive& primitive = primitivehit.first; const PrecalculatedMaterial& material = primitivehit.second; const Hit& hit = primitivehit.third; bool hastransparency = std::any_of( material.refractivity.begin( ), material.refractivity.end( ), real_compare<std::less<>, 1>( ) ); if ( !hastransparency ) return false; Fur::optional<vec3> oprefractionraydir = refract( ray.direction, hit.inside ? hit.normal * real_neg_one : hit.normal, ior1, ior2 ); if ( !oprefractionraydir ) return false; // Not total internal reflection const vec3& refractionraydir = *oprefractionraydir; Ray refractionray( hit.contact + refractionraydir * scene.Bias(), refractionraydir ); raybounce.ray = refractionray; Bounce( raybounce, refractionray, scene, shader, primitivehit, depth + 1 ); return true; }