add metal material
This commit is contained in:
parent
b827c777e0
commit
93330c85c2
|
@ -1,11 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#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;
|
||||
|
||||
|
|
41
src/main.cpp
41
src/main.cpp
|
@ -4,6 +4,7 @@
|
|||
#include "sphere.h"
|
||||
#include "colour.h"
|
||||
#include "camera.h"
|
||||
#include "material.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -23,8 +24,15 @@ colour ray_colour(const ray& r, const hittable& world, int depth)
|
|||
|
||||
if (world.hit(r, 0.001, infinity, rec))
|
||||
{
|
||||
point3 target = rec.p + rec.normal + random_in_hemisphere(rec.normal);
|
||||
return 0.5 * ray_colour(ray(rec.p, target - rec.p), world, depth-1);
|
||||
ray scattered;
|
||||
colour attenuation;
|
||||
|
||||
if (rec.mat_ptr->scatter(r, rec, attenuation, scattered))
|
||||
{
|
||||
return attenuation * ray_colour(scattered, world, depth-1);
|
||||
}
|
||||
|
||||
return colour(0,0,0);
|
||||
}
|
||||
|
||||
vec3 unit_direction = unit_vector(r.direction());
|
||||
|
@ -40,18 +48,25 @@ int main()
|
|||
{
|
||||
std::cout << "P3\n" << WIDTH << ' ' << HEIGHT << "\n255\n";
|
||||
|
||||
auto viewport_height = 2.0;
|
||||
auto viewport_width = ASPECT_RATIO * viewport_height;
|
||||
auto focal_length = 1.0;
|
||||
|
||||
auto origin = point3(0, 0, 0);
|
||||
auto horizontal = vec3(viewport_width, 0, 0);
|
||||
auto vertical = vec3(0, viewport_height, 0);
|
||||
auto lower_left_corner = origin - horizontal/2 - vertical/2 - vec3(0,0,focal_length);
|
||||
|
||||
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));
|
||||
|
||||
world.add(make_shared<sphere>(
|
||||
point3(0,0,-1),
|
||||
0.5,
|
||||
make_shared<lambertian>(colour(0.7,0.3,0.3))));
|
||||
world.add(make_shared<sphere>(
|
||||
point3(0,-100.5,-1),
|
||||
100,
|
||||
make_shared<lambertian>(colour(0.8,0.8,0.0))));
|
||||
|
||||
world.add(make_shared<sphere>(
|
||||
point3(1,0,-1),
|
||||
0.5,
|
||||
make_shared<metal>(colour(0.8,0.6,0.2))));
|
||||
world.add(make_shared<sphere>(
|
||||
point3(-1,0,-1),
|
||||
0.5,
|
||||
make_shared<metal>(colour(0.8,0.8,0.8))));
|
||||
|
||||
camera cam;
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include "rtweekend.h"
|
||||
#include "hittable.h"
|
||||
|
||||
class material
|
||||
{
|
||||
public:
|
||||
virtual bool scatter(
|
||||
const ray& r_in,
|
||||
const hit_record& rec,
|
||||
colour& attenuation,
|
||||
ray& scattered) const = 0;
|
||||
};
|
||||
|
||||
class lambertian : public material
|
||||
{
|
||||
public:
|
||||
lambertian(const colour& a) : albedo_(a) {}
|
||||
|
||||
virtual bool scatter(
|
||||
const ray& r_in,
|
||||
const hit_record& rec,
|
||||
colour& attenuation,
|
||||
ray& scattered) const
|
||||
{
|
||||
vec3 scatter_direction = rec.normal + random_unit_vector();
|
||||
scattered = ray(rec.p, scatter_direction);
|
||||
attenuation = albedo_;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
colour albedo_;
|
||||
};
|
||||
|
||||
class metal : public material
|
||||
{
|
||||
public:
|
||||
metal(const colour& a) : albedo_(a) {}
|
||||
|
||||
virtual bool scatter(
|
||||
const ray& r_in,
|
||||
const hit_record& rec,
|
||||
colour& attenuation,
|
||||
ray& scattered) const
|
||||
{
|
||||
vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal);
|
||||
scattered = ray(rec.p, reflected);
|
||||
attenuation = albedo_;
|
||||
return dot(scattered.direction(), rec.normal) > 0;
|
||||
}
|
||||
|
||||
private:
|
||||
colour albedo_;
|
||||
};
|
|
@ -7,15 +7,18 @@ class sphere : public hittable
|
|||
{
|
||||
public:
|
||||
sphere() {}
|
||||
sphere(point3 centre, double r) :
|
||||
sphere(point3 centre, double r, shared_ptr<material> m) :
|
||||
centre_(centre),
|
||||
radius_(r) {};
|
||||
radius_(r),
|
||||
mat_ptr_(m)
|
||||
{};
|
||||
|
||||
virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const;
|
||||
|
||||
private:
|
||||
point3 centre_;
|
||||
double radius_;
|
||||
shared_ptr<material> mat_ptr_;
|
||||
};
|
||||
|
||||
bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const
|
||||
|
@ -38,6 +41,7 @@ bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) cons
|
|||
|
||||
vec3 outward_normal = (rec.p - centre_) / radius_;
|
||||
rec.set_face_normal(r, outward_normal);
|
||||
rec.mat_ptr = mat_ptr_;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -50,6 +54,7 @@ bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) cons
|
|||
|
||||
vec3 outward_normal = (rec.p - centre_) / radius_;
|
||||
rec.set_face_normal(r, outward_normal);
|
||||
rec.mat_ptr = mat_ptr_;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -159,3 +159,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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue