/** * Ported from paper "Reflections and Refractions in Ray Tracing" by Bram de Greve (2006) * * @param incident * @param normal * @param n1 * @param n2 * @return */ private Refraction getRefraction(Vector incident, Vector normal, float n1, float n2) { float n = n1 / n2; float cosI = -normal.dot(incident); float sinT2 = n * n * (1.0f - cosI * cosI); if (sinT2 > 1.0) { // TIR return null; } float cosT = (float) Math.sqrt(1.0f - sinT2); Refraction res = new Refraction(); res.direction = incident.mult(n).add(normal.mult(n * cosI - cosT)); // Schlick approximation float r0 = (n1 - n2) / (n1 + n2); r0 *= r0; float cosX = cosI; if (n1 > n2) { cosX = cosT; } float x = 1.0f - cosX; res.reflectionAbility = r0 + (1.0f - r0) * x * x * x * x * x; res.transmissionAbility = 1.0f - res.reflectionAbility; return res; }
private Vector getReflection(Vector direction, Vector normal) { Vector rayDirection = direction.normalize().mult(-1); return normal.mult(normal.dot(rayDirection) * 2).sub(rayDirection); }