Transmission
A glass cube refracts the scene behind it in screen space: the frame is rendered, blurred into a pyramid, and read back through Snell refraction, chromatic dispersion and a Fresnel-weighted environment reflection.
/** Projects a world point onto a top-origin screen-space uv. */
export fn project_to_uv(view_projection: mat4x4f, world_position: vec3f) -> vec2f {
let clip = view_projection * vec4f(world_position, 1.0);
let ndc = clip.xy / max(clip.w, 1e-4);
return vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
}
/** How far past the exit face the transmitted ray is followed before projection. */
const RAY_DISTANCE: f32 = 4.0;
/** Follows one wavelength through the entry and optional exit interfaces. */
export fn transmitted_ray(entry: vec3f, incident: vec3f, normal: vec3f, eta: f32, exit_normal: vec3f, thickness: f32, double_amount: f32) -> vec4f {
let inside = refract(incident, normal, eta);
if (dot(inside, inside) < 1e-6) { return vec4f(entry, 0.0); }
let exit_position = entry + inside * thickness;
if (double_amount < 1e-3) { return vec4f(exit_position + inside * RAY_DISTANCE, 1.0); }
let outgoing = refract(inside, -exit_normal, 1.0 / eta);
if (dot(outgoing, outgoing) < 1e-6) { return vec4f(exit_position + inside * RAY_DISTANCE, 1.0); }
return vec4f(exit_position + outgoing * RAY_DISTANCE, 1.0);
}