| ... | ... |
@@ -3,6 +3,7 @@ |
| 3 | 3 |
{ "include": ["@<glm/ext/(matrix|vector)_(float|u?int).*>", "public", "<glm/glm.hpp>", "public"] },
|
| 4 | 4 |
{ "symbol": ["glm::lookAt", "public", "<glm/ext/matrix_transform.hpp>", "public"] },
|
| 5 | 5 |
{ "symbol": ["glm::perspective", "public", "<glm/ext/matrix_clip_space.hpp>", "public"] },
|
| 6 |
+ { "symbol": ["glm::project", "public", "<glm/ext/matrix_projection.hpp>", "public"] },
|
|
| 6 | 7 |
{ "symbol": ["glm::unProject", "public", "<glm/ext/matrix_projection.hpp>", "public"] },
|
| 7 | 8 |
{ "symbol": ["glm::convertLinearToSRGB", "public", "<glm/gtc/color_space.hpp>", "public"] },
|
| 8 | 9 |
] |
| ... | ... |
@@ -56,6 +56,7 @@ struct Trace |
| 56 | 56 |
{
|
| 57 | 57 |
float distance; |
| 58 | 58 |
Material material; |
| 59 |
+ vec3 miss; |
|
| 59 | 60 |
}; |
| 60 | 61 |
|
| 61 | 62 |
//// Circle |
| ... | ... |
@@ -69,15 +70,20 @@ struct Circle |
| 69 | 70 |
auto const offs = center - ray.origin; |
| 70 | 71 |
auto const proj = dot(offs, ray.direction); |
| 71 | 72 |
if (proj < 0.0F) // Past. |
| 72 |
- return {infinity, {}};
|
|
| 73 |
+ return {infinity, {}, {}};
|
|
| 73 | 74 |
auto const perp2 = dot(offs, offs) - proj * proj; |
| 74 | 75 |
auto const pene2 = radius * radius - perp2; |
| 75 | 76 |
if (pene2 < 0.0F) // Miss. |
| 76 |
- return {infinity, {}};
|
|
| 77 |
+ {
|
|
| 78 |
+ auto const poin = ray.point(proj); |
|
| 79 |
+ auto const rati = 1.0F - radius * inversesqrt(perp2); |
|
| 80 |
+ auto const miss = rati * (center - poin); |
|
| 81 |
+ return {proj, material, miss};
|
|
| 82 |
+ } |
|
| 77 | 83 |
auto const dist = proj - sqrt(pene2); |
| 78 | 84 |
if (dist < 0.0F) // Inside. |
| 79 |
- return {infinity, {}};
|
|
| 80 |
- return {dist, material};
|
|
| 85 |
+ return {infinity, {}, {}};
|
|
| 86 |
+ return {dist, material, vec3(0.0F)};
|
|
| 81 | 87 |
} |
| 82 | 88 |
}; |
| 83 | 89 |
|
| ... | ... |
@@ -91,7 +97,7 @@ struct Scene |
| 91 | 97 |
Shapes shapes; |
| 92 | 98 |
Trace trace(Ray const & ray) const |
| 93 | 99 |
{
|
| 94 |
- auto nearest = Trace{infinity, background};
|
|
| 100 |
+ auto nearest = Trace{infinity, background, {}};
|
|
| 95 | 101 |
for (auto const & shape : shapes) |
| 96 | 102 |
{
|
| 97 | 103 |
auto const trace = shape.trace(ray); |
| ... | ... |
@@ -122,6 +128,16 @@ struct Camera |
| 122 | 128 |
auto const direction = normalize(world.xyz() - position); |
| 123 | 129 |
return Ray{position, direction};
|
| 124 | 130 |
} |
| 131 |
+ vec2 project(uvec2 const & size, vec3 const & point) const |
|
| 132 |
+ {
|
|
| 133 |
+ auto const aspect = (float)size.x / (float)size.y; |
|
| 134 |
+ auto const viewport = uvec4(0, 0, size); |
|
| 135 |
+ auto const up = vec3(0.0F, 1.0F, 0.0F); |
|
| 136 |
+ auto const view = glm::lookAt(position, target, up); |
|
| 137 |
+ auto const proj = glm::perspective(fovy, aspect, near, far); |
|
| 138 |
+ auto const window = glm::project(point, view, proj, viewport); |
|
| 139 |
+ return window.xy(); |
|
| 140 |
+ } |
|
| 125 | 141 |
}; |
| 126 | 142 |
|
| 127 | 143 |
//// ACES |
| ... | ... |
@@ -220,6 +236,15 @@ int main(int argc, char const * argv[]) |
| 220 | 236 |
{
|
| 221 | 237 |
auto trace = scene.trace(ray); |
| 222 | 238 |
auto color = trace.material.color; |
| 239 |
+ if (trace.miss != vec3(0.0F)) |
|
| 240 |
+ {
|
|
| 241 |
+ auto const point = ray.point(trace.distance); |
|
| 242 |
+ auto const dist = distance( |
|
| 243 |
+ camera.project(size, point), |
|
| 244 |
+ camera.project(size, point + trace.miss) |
|
| 245 |
+ ); |
|
| 246 |
+ color.a *= 1.0F - clamp(dist, 0.0F, 1.0F); |
|
| 247 |
+ } |
|
| 223 | 248 |
rgb += color.rgb() * color.a * trans; |
| 224 | 249 |
trans *= 1.0F - color.a; |
| 225 | 250 |
if (trace.distance == infinity || trans == 0.0F) |