glm::vec3 indirect(const glm::vec3 &c, const glm::vec3 &p, const glm::vec3 &n, const Glass &glass, int iterations) { float ior = 1.5f; // Calcul du rayon réfléchi glm::vec3 direction = reflect(c,n); glm::vec3 directionNorm = glm::normalize(direction); Ray rayReflexion{p+directionNorm*0.1f, directionNorm}; // Calcul du rayon réfracté glm::vec3 vecRefract; refract(-c, n, ior, vecRefract); Ray rayRefraction{p+vecRefract*0.1f, vecRefract}; // Calcul du coefficient reflechi/refracte float coeff = fresnelR(-c, n, ior); float rand = random_u(); if (rand < coeff) { return radiance(rayReflexion, iterations-1); } return radiance(rayRefraction, iterations-1) * glass.color; //return radiance(rayReflexion, iterations-1) * coeff + radiance(rayRefraction, iterations-1) * (1- coeff); }
// Fresnel coeficient of transmission. // Normal point outside the surface // ior is n0 / n1 where n0 is inside and n1 is outside float fresnelR(const glm::vec3 i, const glm::vec3 n, const float ior) { if(glm::dot(n, i) < 0) return fresnelR(i, n * -1.f, 1.f / ior); float R0 = (ior - 1.f) / (ior + 1.f); R0 *= R0; return R0 + (1.f - R0) * std::pow(1.f - glm::dot(i, n), 5.f); }
glm::vec3 indirect(const Ray &rOrigine, const Ray &rReflect, const glm::vec3 &p, const glm::vec3 & n, int countdown, const Glass &glass) { float fresnel = fresnelR(-rOrigine.direction,n, 1.5); glm::vec3 refracted; bool canRefract = refract(-rOrigine.direction, n, 1.5, refracted); Ray rRefracted{p+refracted*0.1f, refracted}; if(canRefract) { float u = random_u(); if(u < fresnel) return radiance(rReflect, countdown); else return radiance(rRefracted, countdown); } //return fresnel*radiance(rReflect, countdown)+(1-fresnel)*radiance(rRefracted, countdown); else return fresnel*radiance(rReflect, countdown); }