Skip to content

Commit 4018b39

Browse files
authored
Scene (#10)
- Fix typo. - Add `t` to `Hit`.
1 parent 3479f6a commit 4018b39

File tree

8 files changed

+101
-17
lines changed

8 files changed

+101
-17
lines changed

tray/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ target_sources(${PROJECT_NAME} PRIVATE
88
src/tray/io.cpp
99
src/tray/io.hpp
1010
src/tray/light.hpp
11+
src/tray/material.hpp
1112
src/tray/nvec3.hpp
1213
src/tray/ray.hpp
14+
src/tray/renderable.hpp
1315
src/tray/rgb.hpp
16+
src/tray/scene.cpp
17+
src/tray/scene.hpp
1418
src/tray/sphere.hpp
1519
src/tray/vec.hpp
1620
src/tray/viewport.hpp

tray/src/main.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#include <tray/hit.hpp>
22
#include <tray/image.hpp>
33
#include <tray/io.hpp>
4-
#include <tray/light.hpp>
5-
#include <tray/ray.hpp>
4+
#include <tray/scene.hpp>
65
#include <tray/viewport.hpp>
76
#include <algorithm>
87
#include <iostream>
@@ -28,27 +27,26 @@ int main() {
2827
static constexpr auto vertical = fvec3{0.0f, viewport.extent.y(), 0.0f};
2928
static constexpr auto top_left = origin + 0.5f * (-horizontal + vertical) + fvec3{0.0f, 0.0f, -viewport.depth};
3029

31-
static constexpr fvec3 gradient[] = {Rgb::from_hex(0xffffff).to_f32(), Rgb::from_hex(0x002277).to_f32()};
32-
auto image = Image{extent};
33-
auto const sphere = Sphere{.centre = {0.0f, 0.0f, -5.0f}, .radius = 1.0f};
34-
DirLight const lights[] = {
35-
DirLight{.intensity = {0.0f, 1.0f, 1.0f}, .direction = fvec3{-1.0f}},
36-
DirLight{.intensity = {0.5f, 0.0f, 0.0f}, .direction = fvec3{0.0f, 0.0f, -1.0f}},
30+
auto scene = Scene{};
31+
scene.renderables.push_back(Sphere{.centre = {0.0f, 0.0f, -5.0f}, .radius = 1.0f});
32+
scene.renderables.push_back({
33+
Sphere{.centre = {0.5f, -2.0f, -10.0f}, .radius = 5.0f},
34+
Material{.diffuse = {0.2f, 0.8f, 0.7f}},
35+
});
36+
scene.dir_lights = {
37+
DirLight{.intensity = {1.0f, 1.0f, 1.0f}, .direction = fvec3{-1.0f}},
38+
DirLight{.intensity = {0.5f, 0.3f, 0.3f}, .direction = fvec3{0.0f, 0.0f, -1.0f}},
3739
};
3840

41+
auto image = Image{extent};
42+
3943
for (std::uint32_t row = 0; row < image.extent().y(); ++row) {
4044
auto const yt = static_cast<float>(row) / static_cast<float>(image.extent().y() - 1);
4145
for (std::uint32_t col = 0; col < image.extent().x(); ++col) {
4246
auto const xt = static_cast<float>(col) / static_cast<float>(image.extent().x() - 1);
4347
auto const dir = top_left + xt * horizontal - yt * vertical - origin;
4448
auto const ray = Ray{origin, dir};
45-
auto hit = Hit{};
46-
if (hit(ray, sphere)) {
47-
image[{row, col}] = Rgb::from_f32(clamp(DirLight::combine(lights, hit.normal)));
48-
continue;
49-
}
50-
auto const t = 0.5f * (ray.direction.vec().y() + 1.0f);
51-
image[{row, col}] = Rgb::from_f32(lerp(gradient[0], gradient[1], t));
49+
image[{row, col}] = Rgb::from_f32(clamp(scene.raycast(ray)));
5250
}
5351
}
5452

tray/src/tray/hit.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace tray {
55
namespace {
6-
constexpr float smallet_positive_root(std::span<float const, 2> roots) {
6+
constexpr float smallest_positive_root(std::span<float const, 2> roots) {
77
if (roots[0] < 0.0f) { return roots[1]; }
88
if (roots[1] < 0.0f) { return roots[0]; }
99
return std::min(roots[0], roots[1]);
@@ -19,7 +19,7 @@ bool Hit::operator()(Ray const& ray, Sphere const& sphere) {
1919

2020
auto const sqd = std::sqrt(discriminant);
2121
float const roots[] = {0.5f * (-b - sqd), 0.5f * (-b + sqd)};
22-
auto const t = smallet_positive_root(roots);
22+
t = smallest_positive_root(roots);
2323
if (t < 0.0f) { return false; }
2424

2525
point = ray.at(t);

tray/src/tray/hit.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace tray {
77
struct Hit {
88
fvec3 point{};
99
nvec3 normal{};
10+
float t{};
1011

1112
bool operator()(Ray const& ray, Sphere const& sphere);
1213
};

tray/src/tray/material.hpp

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

tray/src/tray/renderable.hpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
#include <tray/hit.hpp>
3+
#include <tray/material.hpp>
4+
#include <memory>
5+
6+
namespace tray {
7+
template <typename T>
8+
concept Hittable = requires(T const& t, Ray const& ray) {
9+
Hit{}(ray, t);
10+
};
11+
12+
class Renderable {
13+
public:
14+
template <Hittable T>
15+
Renderable(T t, Material material = {}) : material{material}, m_model{std::make_unique<Model<T>>(std::move(t))} {}
16+
17+
bool hit(Hit& out, Ray const& ray) const { return m_model->hit(out, ray); }
18+
19+
Material material{};
20+
21+
private:
22+
struct Base {
23+
virtual ~Base() = default;
24+
virtual bool hit(Hit& out, Ray const& ray) const = 0;
25+
};
26+
27+
template <Hittable T>
28+
struct Model : Base {
29+
T t;
30+
Model(T&& t) : t{std::move(t)} {}
31+
bool hit(Hit& out, Ray const& ray) const override { return out(ray, t); }
32+
};
33+
34+
std::unique_ptr<Base> m_model{};
35+
};
36+
} // namespace tray

tray/src/tray/scene.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <tray/scene.hpp>
2+
3+
namespace tray {
4+
fvec3 Scene::raycast(Ray const& ray) const {
5+
struct {
6+
Renderable const* renderable{};
7+
Hit hit{};
8+
} nearest{};
9+
auto hit = Hit{};
10+
for (auto const& renderable : renderables) {
11+
if (renderable.hit(hit, ray) && (!nearest.renderable || hit.t < nearest.hit.t)) { nearest = {&renderable, hit}; }
12+
}
13+
if (!nearest.renderable) {
14+
auto const t = 0.5f * (ray.direction.vec().y() + 1.0f);
15+
return lerp(background.bottom, background.top, t);
16+
}
17+
return DirLight::combine(dir_lights, nearest.hit.normal) * nearest.renderable->material.diffuse;
18+
}
19+
} // namespace tray

tray/src/tray/scene.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#pragma once
2+
#include <tray/light.hpp>
3+
#include <tray/renderable.hpp>
4+
#include <tray/rgb.hpp>
5+
#include <vector>
6+
7+
namespace tray {
8+
struct Scene {
9+
std::vector<DirLight> dir_lights{};
10+
std::vector<Renderable> renderables{};
11+
struct {
12+
fvec3 top{Rgb::from_hex(0x002277).to_f32()};
13+
fvec3 bottom{Rgb::from_hex(0xffffff).to_f32()};
14+
} background{};
15+
16+
fvec3 raycast(Ray const& ray) const;
17+
};
18+
} // namespace tray

0 commit comments

Comments
 (0)