add metal material
This commit is contained in:
parent
b827c777e0
commit
93330c85c2
|
@ -11,9 +11,9 @@ class camera
|
||||||
const double FOCAL_LENGTH = 1.0;
|
const double FOCAL_LENGTH = 1.0;
|
||||||
|
|
||||||
camera() :
|
camera() :
|
||||||
origin_(point3(0,0,0)),
|
origin_ (point3(0,0,0)),
|
||||||
horizontal_(vec3(VIEWPORT_WIDTH,0.0,0.0)),
|
horizontal_ (vec3(VIEWPORT_WIDTH,0.0,0.0)),
|
||||||
vertical_(vec3(0.0, VIEWPORT_HEIGHT, 0.0))
|
vertical_ (vec3(0.0, VIEWPORT_HEIGHT, 0.0))
|
||||||
{
|
{
|
||||||
lower_left_corner_ = origin_ - horizontal_/2 - vertical_/2 - vec3(0,0,FOCAL_LENGTH);
|
lower_left_corner_ = origin_ - horizontal_/2 - vertical_/2 - vec3(0,0,FOCAL_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "rtweekend.h"
|
||||||
#include "ray.h"
|
#include "ray.h"
|
||||||
|
|
||||||
|
class material;
|
||||||
|
|
||||||
struct hit_record
|
struct hit_record
|
||||||
{
|
{
|
||||||
point3 p;
|
point3 p;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
double t;
|
shared_ptr<material> mat_ptr;
|
||||||
bool front_face;
|
double t;
|
||||||
|
bool front_face;
|
||||||
|
|
||||||
inline void set_face_normal(const ray& r, const vec3& outward_normal)
|
inline void set_face_normal(const ray& r, const vec3& outward_normal)
|
||||||
{
|
{
|
||||||
|
|
41
src/main.cpp
41
src/main.cpp
|
@ -4,6 +4,7 @@
|
||||||
#include "sphere.h"
|
#include "sphere.h"
|
||||||
#include "colour.h"
|
#include "colour.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
#include "material.h"
|
||||||
|
|
||||||
#include <iostream>
|
#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))
|
if (world.hit(r, 0.001, infinity, rec))
|
||||||
{
|
{
|
||||||
point3 target = rec.p + rec.normal + random_in_hemisphere(rec.normal);
|
ray scattered;
|
||||||
return 0.5 * ray_colour(ray(rec.p, target - rec.p), world, depth-1);
|
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());
|
vec3 unit_direction = unit_vector(r.direction());
|
||||||
|
@ -40,18 +48,25 @@ int main()
|
||||||
{
|
{
|
||||||
std::cout << "P3\n" << WIDTH << ' ' << HEIGHT << "\n255\n";
|
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;
|
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;
|
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_;
|
||||||
|
};
|
13
src/sphere.h
13
src/sphere.h
|
@ -7,15 +7,18 @@ class sphere : public hittable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sphere() {}
|
sphere() {}
|
||||||
sphere(point3 centre, double r) :
|
sphere(point3 centre, double r, shared_ptr<material> m) :
|
||||||
centre_(centre),
|
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;
|
virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
point3 centre_;
|
point3 centre_;
|
||||||
double radius_;
|
double radius_;
|
||||||
|
shared_ptr<material> mat_ptr_;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const
|
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_;
|
vec3 outward_normal = (rec.p - centre_) / radius_;
|
||||||
rec.set_face_normal(r, outward_normal);
|
rec.set_face_normal(r, outward_normal);
|
||||||
|
rec.mat_ptr = mat_ptr_;
|
||||||
|
|
||||||
return true;
|
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_;
|
vec3 outward_normal = (rec.p - centre_) / radius_;
|
||||||
rec.set_face_normal(r, outward_normal);
|
rec.set_face_normal(r, outward_normal);
|
||||||
|
rec.mat_ptr = mat_ptr_;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,3 +159,8 @@ vec3 random_in_hemisphere(const vec3& normal)
|
||||||
return -in_unit_sphere;
|
return -in_unit_sphere;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 reflect(const vec3& v, const vec3& n)
|
||||||
|
{
|
||||||
|
return v - 2*dot(v,n)*n;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue