#ifndef UNITY_REFRACTION_INCLUDED #define UNITY_REFRACTION_INCLUDED //----------------------------------------------------------------------------- // Util refraction //----------------------------------------------------------------------------- struct RefractionModelResult { real dist; // length of the transmission during refraction through the shape float3 positionWS; // out ray position real3 rayWS; // out ray direction }; RefractionModelResult RefractionModelSphere(real3 V, float3 positionWS, real3 normalWS, real ior, real thickness) { // Sphere shape model: // We approximate locally the shape of the object as sphere, that is tangent to the shape. // The sphere has a diameter of {thickness} // The center of the sphere is at {positionWS} - {normalWS} * {thickness} * 0.5 // // So the light is refracted twice: in and out of the tangent sphere // First refraction (tangent sphere in) // Refracted ray real3 R1 = refract(-V, normalWS, 1.0 / ior); // Center of the tangent sphere real3 C = positionWS - normalWS * thickness * 0.5; // Second refraction (tangent sphere out) real NoR1 = dot(normalWS, R1); // Optical depth within the sphere real dist = -NoR1 * thickness; // Out hit point in the tangent sphere real3 P1 = positionWS + R1 * dist; // Out normal real3 N1 = SafeNormalize(C - P1); // Out refracted ray real3 R2 = refract(R1, N1, ior); real N1oR2 = dot(N1, R2); real VoR1 = dot(V, R1); RefractionModelResult result; result.dist = dist; result.positionWS = P1; result.rayWS = R2; return result; } RefractionModelResult RefractionModelBox(real3 V, float3 positionWS, real3 normalWS, real ior, real thickness) { // Plane shape model: // We approximate locally the shape of the object as a plane with normal {normalWS} at {positionWS} // with a thickness {thickness} // Refracted ray real3 R = refract(-V, normalWS, 1.0 / ior); // Optical depth within the thin plane real dist = thickness / max(dot(R, -normalWS), 1e-5f); RefractionModelResult result; result.dist = dist; result.positionWS = positionWS + R * dist; result.rayWS = -V; return result; } #endif