1
0

feat: add metal metarial

This commit is contained in:
Rokas Puzonas 2022-03-13 20:11:34 +02:00
parent cd414d1aeb
commit 14ac9f2ec0
8 changed files with 70828 additions and 70747 deletions

View File

@ -2,6 +2,7 @@
#define COLOR_H
#include "rtweekend.h"
#include "vec3.h"
#include <iostream>

View File

@ -1,11 +1,15 @@
#ifndef HITTABLE_H
#define HITTABLE_H
#include "rtweekend.h"
#include "ray.h"
class material;
struct hit_record {
point3 p;
vec3 normal;
shared_ptr<material> mat_ptr;
double t;
bool front_face;

141472
image.ppm

File diff suppressed because it is too large Load Diff

22
main.cc
View File

@ -1,9 +1,10 @@
#include "rtweekend.h"
#include "color.h"
#include "rtweekend.h"
#include "hittable_list.h"
#include "sphere.h"
#include "camera.h"
#include "material.h"
#include <iostream>
@ -15,8 +16,11 @@ color ray_color(const ray& r, const hittable& world, int depth) {
return color(0, 0, 0);
if (world.hit(r, 0.001, infinity, rec)) {
point3 target = rec.p + rec.normal + random_in_hemisphere(rec.normal);
return 0.5 * ray_color(ray(rec.p, target - rec.p), world, depth-1);
ray scattered;
color attenuation;
if (rec.mat_ptr->scatter(r, rec, attenuation, scattered))
return attenuation * ray_color(scattered, world, depth-1);
return color(0,0,0);
}
vec3 unit_direction = unit_vector(r.direction());
@ -34,8 +38,16 @@ int main() {
// World
hittable_list world;
world.add(make_shared<sphere>(point3(0, 0, -1), 0.5));
world.add(make_shared<sphere>(point3(0, -100.5, -1), 100));
auto material_ground = make_shared<lambertian>(color(0.8, 0.8, 0.0));
auto material_center = make_shared<lambertian>(color(0.7, 0.3, 0.3));
auto material_left = make_shared<metal>(color(0.8, 0.8, 0.8), 0.3);
auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 1.0);
world.add(make_shared<sphere>(point3(0, -100.5, -1), 100, material_ground));
world.add(make_shared<sphere>(point3(0, 0, -1), 0.5, material_center));
world.add(make_shared<sphere>(point3(-1, 0, -1), 0.5, material_left));
world.add(make_shared<sphere>(point3(1, 0, -1), 0.5, material_right));
// Camera
camera cam;

56
material.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef MATERIAL_H
#define MATERIAL_H
#include "hittable.h"
#include "rtweekend.h"
#include "vec3.h"
struct hit_record;
class material {
public:
virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const = 0;
};
class lambertian : public material {
public:
lambertian(const color& a) : albedo(a) {}
bool scatter(
const ray &r_in, const hit_record &rec, color &attenuation, ray &scattered
) const override {
auto scatter_direction = rec.normal + random_in_hemisphere(rec.normal);
// Catch degenerate scatter direction
if (scatter_direction.near_zero())
scatter_direction = rec.normal;
scattered = ray(rec.p, scatter_direction);
attenuation = albedo;
return true;
}
public:
color albedo;
};
class metal : public material {
public:
metal(const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1) {}
bool scatter(
const ray &r_in, const hit_record &rec, color &attenuation, ray &scattered
) const override {
vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal);
scattered = ray(rec.p, reflected + fuzz*random_in_hemisphere(rec.normal));
attenuation = albedo;
return (dot(scattered.direction(), rec.normal) > 0);
}
public:
color albedo;
double fuzz;
};
#endif

View File

@ -36,8 +36,4 @@ inline double random_double(double min, double max) {
return min + (max - min) * random_double();
}
// Common headers
#include "ray.h"
#include "vec3.h"
#endif

View File

@ -7,7 +7,7 @@
class sphere : public hittable {
public:
sphere() {}
sphere(point3 cen, double r) : center(cen), radius(r) {};
sphere(point3 cen, double r, shared_ptr<material> m) : center(cen), radius(r), mat_ptr(m) {};
virtual bool hit(
const ray& r, double t_min, double t_max, hit_record& rec) const override;
@ -15,6 +15,7 @@ class sphere : public hittable {
public:
point3 center;
double radius;
shared_ptr<material> mat_ptr;
};
bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
@ -39,6 +40,7 @@ bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) cons
rec.p = r.at(rec.t);
vec3 outward_normal = (rec.p - center) / radius;
rec.set_face_normal(r, outward_normal);
rec.mat_ptr = mat_ptr;
return true;
}

12
vec3.h
View File

@ -1,10 +1,11 @@
#ifndef VEC3_H
#define VEC3_H
#include "rtweekend.h"
#include <cmath>
#include <iostream>
#include "rtweekend.h"
using std::sqrt;
class vec3 {
@ -54,6 +55,11 @@ class vec3 {
return vec3(random_double(min, max), random_double(min, max), random_double(min, max));
}
bool near_zero() const {
auto s = 1e-8;
return fabs(e[0]) < s && fabs(e[1]) < s && fabs(e[2]) < s;
}
public:
double e[3];
};
@ -128,4 +134,8 @@ vec3 random_in_hemisphere(const vec3& normal) {
return -in_unit_sphere;
}
vec3 reflect(const vec3& v, const vec3& n) {
return v - 2*dot(v,n)*n;
}
#endif