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