Skip to content

Commit d196649

Browse files
authored
Sphere (#8)
1 parent d8881c0 commit d196649

File tree

5 files changed

+61
-0
lines changed

5 files changed

+61
-0
lines changed

tray/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
add_executable(${PROJECT_NAME})
22
target_include_directories(${PROJECT_NAME} PRIVATE src)
33
target_sources(${PROJECT_NAME} PRIVATE
4+
src/tray/hit.cpp
5+
src/tray/hit.hpp
46
src/tray/image.cpp
57
src/tray/image.hpp
68
src/tray/io.cpp
79
src/tray/io.hpp
810
src/tray/nvec3.hpp
911
src/tray/ray.hpp
1012
src/tray/rgb.hpp
13+
src/tray/sphere.hpp
1114
src/tray/vec.hpp
1215
src/tray/viewport.hpp
1316

tray/src/main.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <tray/hit.hpp>
12
#include <tray/image.hpp>
23
#include <tray/io.hpp>
34
#include <tray/ray.hpp>
@@ -18,13 +19,19 @@ int main() {
1819

1920
static constexpr fvec3 gradient[] = {Rgb::from_hex(0xffffff).to_f32(), Rgb::from_hex(0x002277).to_f32()};
2021
auto image = Image{extent};
22+
auto const sphere = Sphere{.centre = {0.0f, 0.0f, -5.0f}, .radius = 1.0f};
2123

2224
for (std::uint32_t row = 0; row < image.extent().y(); ++row) {
2325
auto const yt = static_cast<float>(row) / static_cast<float>(image.extent().y() - 1);
2426
for (std::uint32_t col = 0; col < image.extent().x(); ++col) {
2527
auto const xt = static_cast<float>(col) / static_cast<float>(image.extent().x() - 1);
2628
auto const dir = top_left + xt * horizontal - yt * vertical - origin;
2729
auto const ray = Ray{origin, dir};
30+
auto hit = Hit{};
31+
if (hit(ray, sphere)) {
32+
image[{row, col}] = Rgb::from_f32(0.5f * (hit.normal.vec() + 1.0f));
33+
continue;
34+
}
2835
auto const t = 0.5f * (ray.direction.vec().y() + 1.0f);
2936
image[{row, col}] = Rgb::from_f32(lerp(gradient[0], gradient[1], t));
3037
}

tray/src/tray/hit.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <tray/hit.hpp>
2+
#include <span>
3+
4+
namespace tray {
5+
namespace {
6+
constexpr float smallet_positive_root(std::span<float const, 2> roots) {
7+
if (roots[0] < 0.0f) { return roots[1]; }
8+
if (roots[1] < 0.0f) { return roots[0]; }
9+
return std::min(roots[0], roots[1]);
10+
}
11+
} // namespace
12+
13+
bool Hit::operator()(Ray const& ray, Sphere const& sphere) {
14+
auto const co = ray.origin - sphere.centre;
15+
float const b = 2.0f * dot(ray.direction.vec(), co);
16+
float const c = dot(co, co) - sphere.radius * sphere.radius;
17+
float const discriminant = b * b - 4 * c;
18+
if (discriminant < 0.0f) { return false; }
19+
20+
auto const sqd = std::sqrt(discriminant);
21+
float const roots[] = {0.5f * (-b - sqd), 0.5f * (-b + sqd)};
22+
auto const t = smallet_positive_root(roots);
23+
if (t < 0.0f) { return false; }
24+
25+
point = ray.at(t);
26+
normal = point - sphere.centre;
27+
return true;
28+
}
29+
} // namespace tray

tray/src/tray/hit.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
#include <tray/nvec3.hpp>
3+
#include <tray/ray.hpp>
4+
#include <tray/sphere.hpp>
5+
6+
namespace tray {
7+
struct Hit {
8+
fvec3 point{};
9+
nvec3 normal{};
10+
11+
bool operator()(Ray const& ray, Sphere const& sphere);
12+
};
13+
} // namespace tray

tray/src/tray/sphere.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
#include <tray/vec.hpp>
3+
4+
namespace tray {
5+
struct Sphere {
6+
fvec3 centre{};
7+
float radius{};
8+
};
9+
} // namespace tray

0 commit comments

Comments
 (0)