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