Skip to content

Commit

Permalink
Create metal material #16
Browse files Browse the repository at this point in the history
  • Loading branch information
smercer10 committed Feb 25, 2024
1 parent e8c5655 commit 38cbb0e
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 5 deletions.
12 changes: 9 additions & 3 deletions apps/raydiance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ int main() {

scene world;

auto m = std::make_shared<lambertian>(colour{0.0, 0.0, 0.0});
world.add(std::make_shared<sphere>(point3{0, 0, -1}, 0.5, m));
world.add(std::make_shared<sphere>(point3{0, -100.5, -1}, 100, m));
auto matGround = std::make_shared<lambertian>(colour(0.8, 0.8, 0.0));
auto matCentre = std::make_shared<lambertian>(colour(0.7, 0.3, 0.3));
auto matLeft = std::make_shared<metal>(colour(0.8, 0.8, 0.8), 0.3);
auto matRight = std::make_shared<metal>(colour(0.8, 0.6, 0.2), 1.0);

world.add(std::make_shared<sphere>(point3(0.0, -100.5, -1.0), 100.0, matGround));
world.add(std::make_shared<sphere>(point3(0.0, 0.0, -1.0), 0.5, matCentre));
world.add(std::make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.5, matLeft));
world.add(std::make_shared<sphere>(point3(1.0, 0.0, -1.0), 0.5, matRight));

camera cam;

Expand Down
5 changes: 5 additions & 0 deletions include/raydiance/colour.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ inline colour operator+(const colour &c1, const colour &c2) {
return {c1.r() + c2.r(), c1.g() + c2.g(), c1.b() + c2.b()};
}

// Hadamard product
inline colour operator*(const colour &c1, const colour &c2) {
return {c1.r() * c2.r(), c1.g() * c2.g(), c1.b() * c2.b()};
}

inline colour operator*(double a, const colour &c) {
return {a * c.r(), a * c.g(), a * c.b()};
}
Expand Down
11 changes: 11 additions & 0 deletions include/raydiance/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,15 @@ class lambertian : public material {

private:
colour albedo;
};

class metal : public material {
public:
metal(const colour &a, double f) : albedo(a), fuzz(f < 1 ? f : 1) {}

bool scatter(const ray &rIn, const intersection &i, colour &attenuation, ray &scattered) const override;

private:
colour albedo;
double fuzz;
};
4 changes: 4 additions & 0 deletions include/raydiance/vec3.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,8 @@ inline vec3 randomVecOnHemisphere(const vec3 &normal) {
} else {
return -onUnitSphere;
}
}

inline vec3 reflect(const vec3 &v, const vec3 &n) {
return v - 2 * dot(v, n) * n;
}
9 changes: 7 additions & 2 deletions src/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,14 @@ colour camera::getRayColour(const ray &r, int depth, const object &world) {

// If the ray hits an object, return a colour based on the normal
if (world.isHit(r, interval{0.001, infinity}, i)) {
vec3 direction = i.normal + randomUnitVector();
ray scattered;
colour attenuation;

return 0.5 * getRayColour(ray{i.p, direction}, depth - 1, world);
if (i.mat->scatter(r, i, attenuation, scattered)) {
return attenuation * getRayColour(scattered, depth - 1, world);
}

return colour{0.0, 0.0, 0.0};
}

// If the ray doesn't hit any objects, return a gradient background
Expand Down
7 changes: 7 additions & 0 deletions src/material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ bool lambertian::scatter(const ray &rIn, const intersection &i, colour &attenuat
attenuation = albedo;
return true;
}
bool metal::scatter(const ray &rIn, const intersection &i, colour &attenuation, ray &scattered) const {
vec3 reflected{reflect(unitVector(rIn.direction()), i.normal)};
scattered = ray{i.p, reflected + fuzz * randomUnitVector()};
attenuation = albedo;

return dot(scattered.direction(), i.normal) > 0;
}
9 changes: 9 additions & 0 deletions tests/colour_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ TEST(ColourHelperTest, Addition) {
EXPECT_DOUBLE_EQ(c3.b(), 1.7);
}

TEST(ColourHelperTest, HadamardProduct) {
colour c1(0.5, 0.6, 0.7);
colour c2(0.0, 0.1, 1.0);
colour c3 = c1 * c2;
EXPECT_DOUBLE_EQ(c3.r(), 0.0);
EXPECT_DOUBLE_EQ(c3.g(), 0.06);
EXPECT_DOUBLE_EQ(c3.b(), 0.7);
}

TEST(ColourHelperTest, ScalarMultiplication) {
colour c1(0.5, 0.6, 0.7);
colour c2 = 2.0 * c1;
Expand Down
16 changes: 16 additions & 0 deletions tests/vec3_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,20 @@ TEST(Vec3HelperTest, UnitVector) {
EXPECT_DOUBLE_EQ(v2.x(), 0.476731294622796);
EXPECT_DOUBLE_EQ(v2.y(), 0.572077553547355);
EXPECT_DOUBLE_EQ(v2.z(), 0.667423812471915);
}

TEST(Vec3HelperTest, Reflect) {
vec3 v1(0.5, 0.6, 0.7);
vec3 n1(0.1, -0.2, 0.5);
vec3 r1 = reflect(v1, n1);
EXPECT_DOUBLE_EQ(r1.x(), 0.44400000000000001);
EXPECT_DOUBLE_EQ(r1.y(), 0.71199999999999997);
EXPECT_DOUBLE_EQ(r1.z(), 0.41999999999999998);

vec3 v2(0.5, 0.6, 0.7);
vec3 n2(0.0, 0.0, 0.0);
vec3 r2 = reflect(v2, n2);
EXPECT_DOUBLE_EQ(r2.x(), 0.5);
EXPECT_DOUBLE_EQ(r2.y(), 0.6);
EXPECT_DOUBLE_EQ(r2.z(), 0.7);
}

0 comments on commit 38cbb0e

Please sign in to comment.