include/mcrt/ray.hh
// Perfect refraction from air to high density
Perfect refraction from air to high density
Perfect refraction from air to high density
inline mcrt::Ray mcrt::Ray::refract(const glm::dvec3& hitPosition, const glm::dvec3& surfaceNormal,
                             double refractionIndex) const {
    double cosi = glm::clamp(glm::dot(surfaceNormal, direction), -1.0, 1.0);
    bool outside = glm::dot(direction, surfaceNormal) < 0.0;
    glm::dvec3 bias = surfaceNormal*Ray::EPSILON;
    double n1 = 1.0;
    double n2 = refractionIndex;
    glm::dvec3 normal = surfaceNormal;
    glm::dvec3 refractionDir;
    if(cosi < 0.0)
        cosi = -cosi;
    else {
        std::swap(n1,n2);
        normal = -normal;
    }
    double n = n1 / n2;
    double k = 1.0 - n * n * (1.0 - cosi * cosi);
    if(k < 0.0)
        refractionDir = glm::dvec3(0.0);
    else
        refractionDir = n * direction + (n * cosi - glm::sqrt(k)) * normal;
    return { hitPosition + (outside ? -bias : bias), refractionDir };
}
inline mcrt :: Ray mcrt :: Ray :: refract ( const glm :: dvec3 & hitPosition , const glm :: dvec3 & surfaceNormal , double refractionIndex ) const { double cosi = glm :: clamp ( glm :: dot ( surfaceNormal , direction ) , -1.0 , 1.0 ) ; bool outside = glm :: dot ( direction , surfaceNormal ) < 0.0 ; glm :: dvec3 bias = surfaceNormal * Ray :: EPSILON ; double n1 = 1.0 ; double n2 = refractionIndex ; glm :: dvec3 normal = surfaceNormal ; glm :: dvec3 refractionDir ; if ( cosi < 0.0 ) cosi = - cosi ; else { std :: swap ( n1 , n2 ) ; normal = - normal ; } double n = n1 / n2 ; double k = 1.0 - n * n * ( 1.0 - cosi * cosi ) ; if ( k < 0.0 ) refractionDir = glm :: dvec3 ( 0.0 ) ; else refractionDir = n * direction + ( n * cosi - glm :: sqrt ( k ) ) * normal ; return { hitPosition + ( outside ? - bias : bias ) , refractionDir } ; }
Perfect refraction from air to high density
Perfect refraction from air to high density