A game about forced loneliness, made by TACStudios
1#ifndef UNITY_REFRACTION_INCLUDED
2#define UNITY_REFRACTION_INCLUDED
3
4//-----------------------------------------------------------------------------
5// Util refraction
6//-----------------------------------------------------------------------------
7
8struct RefractionModelResult
9{
10 real dist; // length of the transmission during refraction through the shape
11 float3 positionWS; // out ray position
12 real3 rayWS; // out ray direction
13};
14
15RefractionModelResult RefractionModelSphere(real3 V, float3 positionWS, real3 normalWS, real ior, real thickness)
16{
17 // Sphere shape model:
18 // We approximate locally the shape of the object as sphere, that is tangent to the shape.
19 // The sphere has a diameter of {thickness}
20 // The center of the sphere is at {positionWS} - {normalWS} * {thickness} * 0.5
21 //
22 // So the light is refracted twice: in and out of the tangent sphere
23
24 // First refraction (tangent sphere in)
25 // Refracted ray
26 real3 R1 = refract(-V, normalWS, 1.0 / ior);
27 // Center of the tangent sphere
28 real3 C = positionWS - normalWS * thickness * 0.5;
29
30 // Second refraction (tangent sphere out)
31 real NoR1 = dot(normalWS, R1);
32 // Optical depth within the sphere
33 real dist = -NoR1 * thickness;
34 // Out hit point in the tangent sphere
35 real3 P1 = positionWS + R1 * dist;
36 // Out normal
37 real3 N1 = SafeNormalize(C - P1);
38 // Out refracted ray
39 real3 R2 = refract(R1, N1, ior);
40 real N1oR2 = dot(N1, R2);
41 real VoR1 = dot(V, R1);
42
43 RefractionModelResult result;
44 result.dist = dist;
45 result.positionWS = P1;
46 result.rayWS = R2;
47
48 return result;
49}
50
51RefractionModelResult RefractionModelBox(real3 V, float3 positionWS, real3 normalWS, real ior, real thickness)
52{
53 // Plane shape model:
54 // We approximate locally the shape of the object as a plane with normal {normalWS} at {positionWS}
55 // with a thickness {thickness}
56
57 // Refracted ray
58 real3 R = refract(-V, normalWS, 1.0 / ior);
59
60 // Optical depth within the thin plane
61 real dist = thickness / max(dot(R, -normalWS), 1e-5f);
62
63 RefractionModelResult result;
64 result.dist = dist;
65 result.positionWS = positionWS + R * dist;
66 result.rayWS = -V;
67
68 return result;
69}
70#endif