Browse code

Add material alpha

Robert Cranston authored on 02/08/2024 12:42:45
Showing 2 changed files

1 1
new file mode 100644
2 2
Binary files /dev/null and b/doc/05_material_alpha.tga differ
... ...
@@ -40,10 +40,17 @@ struct Ray
40 40
     }
41 41
 };
42 42
 
43
+//// Material
44
+struct Material
45
+{
46
+    float alpha;
47
+};
48
+
43 49
 //// Trace
44 50
 struct Trace
45 51
 {
46
-    float distance;
52
+    float    distance;
53
+    Material material;
47 54
     explicit operator bool() const
48 55
     {
49 56
         return distance < infinity;
... ...
@@ -53,22 +60,23 @@ struct Trace
53 60
 //// Sphere
54 61
 struct Sphere
55 62
 {
56
-    vec3  center;
57
-    float radius;
63
+    vec3     center;
64
+    float    radius;
65
+    Material material;
58 66
     Trace trace(Ray const & ray) const
59 67
     {
60 68
         auto const offs = center - ray.origin;
61 69
         auto const proj = dot(offs, ray.direction);
62 70
         if (proj < 0.0F)
63
-            return {infinity}; // Past.
71
+            return {infinity, {}}; // Past.
64 72
         auto const perp2 = dot(offs, offs) - proj * proj;
65 73
         auto const over2 = radius * radius - perp2;
66 74
         if (over2 < 0.0F)
67
-            return {infinity}; // Miss.
75
+            return {infinity, {}}; // Miss.
68 76
         auto const dist = proj - sqrt(over2);
69 77
         if (dist < 0.0F)
70
-            return {infinity}; // Inside.
71
-        return {dist}; // Hit.
78
+            return {infinity, {}}; // Inside.
79
+        return {dist, material}; // Hit.
72 80
     }
73 81
 };
74 82
 
... ...
@@ -81,7 +89,7 @@ struct Scene
81 89
     Shapes shapes;
82 90
     Trace trace(Ray const & ray) const
83 91
     {
84
-        auto nearest = Trace{infinity};
92
+        auto nearest = Trace{infinity, {}};
85 93
         for (auto const & shape : shapes)
86 94
         {
87 95
             auto const trace = shape.trace(ray);
... ...
@@ -253,12 +261,12 @@ int main(int argc, char const * argv[])
253 261
     );
254 262
     auto scene = Scene{
255 263
         { // shapes
256
-            Sphere{{   6.0F,  -4.0F,  -24.0F}, 12.0F},
257
-            Sphere{{   2.0F,   6.0F,  -16.0F},  8.0F},
258
-            Sphere{{  -4.0F,   0.0F,  -10.0F},  4.0F},
259
-            Sphere{{   0.0F,  -4.0F,   -6.0F},  1.0F},
260
-            Sphere{{  -1.1F,   0.8F,   -1.1F},  0.2F},
261
-            Sphere{{-110.0F, -80.0F, -110.0F}, 20.0F},
264
+            Sphere{{   6.0F,  -4.0F,  -24.0F}, 12.0F, 1.0F},
265
+            Sphere{{   2.0F,   6.0F,  -16.0F},  8.0F, 1.0F},
266
+            Sphere{{  -4.0F,   0.0F,  -10.0F},  4.0F, 1.0F},
267
+            Sphere{{   0.0F,  -4.0F,   -6.0F},  1.0F, 0.5F},
268
+            Sphere{{  -1.1F,   0.8F,   -1.1F},  0.2F, 1.0F},
269
+            Sphere{{-110.0F, -80.0F, -110.0F}, 20.0F, 1.0F},
262 270
         },
263 271
     };
264 272
     //// Render
... ...
@@ -267,13 +275,15 @@ int main(int argc, char const * argv[])
267 275
         auto ray    = camera.ray(frag_coord, depth_range);
268 276
         auto trace  = Trace{};
269 277
         auto traces = 0;
270
-        while ((trace = scene.trace(ray)))
278
+        auto trans  = 1.0F;
279
+        while (trans != 0.0F && (trace = scene.trace(ray)))
271 280
         {
272 281
             ++traces;
282
+            trans *= 1.0F - trace.material.alpha;
273 283
             ray = ray.resumed(trace.distance);
274 284
         }
275 285
         auto const rgb   = vec3(1.0F / (1.0F + (float)traces));
276
-        auto const alpha = (bool)traces;
286
+        auto const alpha = 1.0F - trans;
277 287
         return vec4(rgb, alpha);
278 288
     });
279 289
     //// Finalize