Skip to content

Commit 6fc86c7

Browse files
committed
Add Viewport, cleanup Ray / main
1 parent 38bd48c commit 6fc86c7

File tree

4 files changed

+70
-10
lines changed

4 files changed

+70
-10
lines changed

tray/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ target_sources(${PROJECT_NAME} PRIVATE
99
src/tray/ray.hpp
1010
src/tray/rgb.hpp
1111
src/tray/vec.hpp
12+
src/tray/viewport.hpp
1213

1314
src/main.cpp
1415
)

tray/src/main.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
#include <tray/image.hpp>
22
#include <tray/io.hpp>
33
#include <tray/ray.hpp>
4-
#include <tray/vec.hpp>
4+
#include <tray/viewport.hpp>
55
#include <iostream>
66
#include <span>
77

88
using namespace tray;
99

1010
int main() {
1111
static constexpr auto extent = uvec2{400U, 300U};
12-
static constexpr auto origin = fvec3{0.0f, 0.0f, 0.0f};
13-
static constexpr auto horizontal = fvec3(extent.x() / 100.0f, 0.0f, 0.0f);
14-
static constexpr auto vertical = fvec3(0.0f, extent.y() / 100.0f, 0.0f);
15-
static constexpr auto lower_left = origin - horizontal / 2.0f - vertical / 2.0f - fvec3{0.0f, 0.0f, 1.0f};
12+
static constexpr auto viewport = Viewport::make(extent, 2.0f, 2.0f);
13+
static constexpr auto origin = fvec3{};
14+
15+
static constexpr auto horizontal = fvec3{viewport.extent.x(), 0.0f, 0.0f};
16+
static constexpr auto vertical = fvec3{0.0f, viewport.extent.y(), 0.0f};
17+
static constexpr auto top_left = origin + 0.5f * (-horizontal + vertical) + fvec3{0.0f, 0.0f, -viewport.depth};
18+
19+
static constexpr fvec3 gradient[] = {Rgb::from_hex(0xffffff).to_f32(), Rgb::from_hex(0x002277).to_f32()};
1620
auto image = Image{extent};
21+
1722
for (std::uint32_t row = 0; row < image.extent().y(); ++row) {
18-
auto const yt = static_cast<float>(row) / static_cast<float>(image.extent().y());
23+
auto const yt = static_cast<float>(row) / static_cast<float>(image.extent().y() - 1);
1924
for (std::uint32_t col = 0; col < image.extent().x(); ++col) {
20-
auto const xt = static_cast<float>(col) / static_cast<float>(image.extent().x());
21-
auto const ray = Ray{origin, lower_left + xt * horizontal + yt * vertical - origin};
22-
auto const t = 0.5f * (normalize(ray.direction.vec()).y() + 1.0f);
23-
image[{row, col}] = Rgb::from_f32(Rgb::from_hex(0xff0000).to_f32() * t + (1.0f - t) * Rgb::from_hex(0xffffff).to_f32());
25+
auto const xt = static_cast<float>(col) / static_cast<float>(image.extent().x() - 1);
26+
auto const dir = top_left + xt * horizontal - yt * vertical - origin;
27+
auto const ray = Ray{origin, dir};
28+
auto const t = 0.5f * (ray.direction.vec().y() + 1.0f);
29+
image[{row, col}] = Rgb::from_f32(lerp(gradient[0], gradient[1], t));
2430
}
2531
}
2632

tray/src/tray/ray.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <tray/ray.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 Ray::hit(Sphere const& sphere) const {
14+
auto const co = origin - sphere.centre;
15+
float const b = 2.0f * dot(direction.vec(), co);
16+
float const c = dot(co, co) - sphere.radius * sphere.radius;
17+
float const discriminant = b * b - 4 * c;
18+
return discriminant > 0.0f;
19+
}
20+
21+
Hit Ray::hit2(Sphere const& sphere) const {
22+
auto const co = origin - sphere.centre;
23+
float const b = 2.0f * dot(direction.vec(), co);
24+
float const c = dot(co, co) - sphere.radius * sphere.radius;
25+
float const discriminant = b * b - 4 * c;
26+
if (discriminant < 0.0f) { return {}; }
27+
28+
float const disc_sq = std::sqrt(discriminant);
29+
float const roots[] = {0.5f * (-b - disc_sq), 0.5f * (-b + disc_sq)};
30+
auto const t = smallet_positive_root(roots);
31+
// auto const root = roots[1];
32+
if (t < 0.0f) { return {}; }
33+
34+
auto const position = at(t);
35+
auto const normal = position - sphere.centre;
36+
// assert(normal.z() > 0.0f);
37+
return {position, normal, t};
38+
}
39+
} // namespace tray

tray/src/tray/viewport.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
#include <tray/vec.hpp>
3+
4+
namespace tray {
5+
struct Viewport {
6+
fvec2 extent{1.0f};
7+
float depth{1.0f};
8+
9+
static constexpr Viewport make(uvec2 extent, float depth, float scale = 1.0f) {
10+
auto const ar = static_cast<float>(extent.x()) / static_cast<float>(extent.y());
11+
return ar > 1.0f ? Viewport{fvec2{scale, scale / ar}, depth} : Viewport{fvec2{scale * ar, scale}, depth};
12+
}
13+
};
14+
} // namespace tray

0 commit comments

Comments
 (0)