... | ... |
@@ -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 |