Adding basic materials (lambertian and metallic).
This commit is contained in:
parent
3ae1c040a2
commit
bdb68df296
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
|||||||
*.o
|
*.o
|
||||||
wtracer
|
wtracer
|
||||||
image.ppm
|
*.ppm
|
||||||
|
6
Makefile
6
Makefile
@ -1,9 +1,9 @@
|
|||||||
CXX = g++
|
CXX = g++
|
||||||
|
|
||||||
CXXFLAGS = -std=c++14 -Wall -Wextra -march=native -Ofast -fopenmp -flto
|
CXXFLAGS = -std=c++14 -Wall -Wextra -Wno-unused-parameter -march=native -Ofast -fopenmp -flto
|
||||||
|
|
||||||
DEPS = util.h vec3.h color.h ray.h camera.h hittable.h hittable_list.h sphere.h
|
DEPS = util.h vec3.h color.h ray.h camera.h hittable.h hittable_list.h sphere.h material.h
|
||||||
OBJ = wtracer.o
|
OBJ = wtracer.o material.o vec3.o
|
||||||
|
|
||||||
TARGET = wtracer
|
TARGET = wtracer
|
||||||
|
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
#ifndef HITTABLE_H
|
#ifndef HITTABLE_H
|
||||||
#define HITTABLE_H
|
#define HITTABLE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "ray.h"
|
#include "ray.h"
|
||||||
|
#include "material.h"
|
||||||
|
|
||||||
|
class Material;
|
||||||
|
|
||||||
struct hit_record {
|
struct hit_record {
|
||||||
Point3 p;
|
Point3 p;
|
||||||
Vec3 normal;
|
Vec3 normal;
|
||||||
|
std::shared_ptr<Material> mat_ptr;
|
||||||
double t;
|
double t;
|
||||||
bool front_face;
|
bool front_face;
|
||||||
|
|
||||||
|
17
material.cpp
Normal file
17
material.cpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include "material.h"
|
||||||
|
|
||||||
|
bool Lambertian::scatter(const Ray& r_in, const hit_record& rec, Color& attenuation, Ray& scattered) const {
|
||||||
|
//Vec3 scatter_direction = rec.normal + random_in_unit_sphere();
|
||||||
|
Vec3 scatter_direction = rec.normal + random_unit_vector();
|
||||||
|
//Vec3 scatter_direction = random_in_hemisphere(rec.normal);
|
||||||
|
scattered = Ray(rec.p, scatter_direction);
|
||||||
|
attenuation = albedo;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Metal::scatter(const Ray& r_in, const hit_record& rec, Color& 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);
|
||||||
|
}
|
33
material.h
Normal file
33
material.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef MATERIAL_H
|
||||||
|
#define MATERIAL_H
|
||||||
|
|
||||||
|
#include "hittable.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) {}
|
||||||
|
|
||||||
|
virtual bool scatter(const Ray& r_in, const hit_record& rec, Color& attenuation, Ray& scattered) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Color albedo;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Metal : public Material {
|
||||||
|
public:
|
||||||
|
Metal(const Color& a) : albedo(a) {}
|
||||||
|
|
||||||
|
virtual bool scatter(const Ray& r_in, const hit_record& rec, Color& attenuation, Ray& scattered) const;
|
||||||
|
private:
|
||||||
|
Color albedo;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MATERIAL_H
|
7
sphere.h
7
sphere.h
@ -2,20 +2,23 @@
|
|||||||
#define SPHERE_H
|
#define SPHERE_H
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "hittable.h"
|
#include "hittable.h"
|
||||||
|
#include "material.h"
|
||||||
#include "vec3.h"
|
#include "vec3.h"
|
||||||
|
|
||||||
class Sphere : public Hittable {
|
class Sphere : public Hittable {
|
||||||
public:
|
public:
|
||||||
Sphere() {}
|
Sphere() {}
|
||||||
Sphere(Point3 cen, double r) : center(cen), radius(r) {}
|
Sphere(Point3 cen, double r, std::shared_ptr<Material> m) : center(cen), radius(r), mat_ptr(m) {}
|
||||||
|
|
||||||
virtual bool hit(const Ray& r, double tmin, double tmax, hit_record& rec) const;
|
virtual bool hit(const Ray& r, double tmin, double tmax, hit_record& rec) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Point3 center;
|
Point3 center;
|
||||||
double radius;
|
double radius;
|
||||||
|
std::shared_ptr<Material> mat_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) const {
|
bool Sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) const {
|
||||||
@ -32,6 +35,7 @@ bool Sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) const
|
|||||||
rec.p = r.at(rec.t);
|
rec.p = r.at(rec.t);
|
||||||
Vec3 outward_normal = (rec.p - center) / radius;
|
Vec3 outward_normal = (rec.p - center) / radius;
|
||||||
rec.set_face_normal(r, outward_normal);
|
rec.set_face_normal(r, outward_normal);
|
||||||
|
rec.mat_ptr = mat_ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
temp = (-half_b + root) / a;
|
temp = (-half_b + root) / a;
|
||||||
@ -40,6 +44,7 @@ bool Sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) const
|
|||||||
rec.p = r.at(rec.t);
|
rec.p = r.at(rec.t);
|
||||||
Vec3 outward_normal = (rec.p - center) / radius;
|
Vec3 outward_normal = (rec.p - center) / radius;
|
||||||
rec.set_face_normal(r, outward_normal);
|
rec.set_face_normal(r, outward_normal);
|
||||||
|
rec.mat_ptr = mat_ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
vec3.cpp
Normal file
24
vec3.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "vec3.h"
|
||||||
|
|
||||||
|
Vec3 random_in_unit_sphere() {
|
||||||
|
while (true) {
|
||||||
|
auto p = Vec3::random(-1, 1);
|
||||||
|
if (p.length_squared() >= 1) continue;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3 random_unit_vector() {
|
||||||
|
auto a = random_double(0, 2*pi);
|
||||||
|
auto z = random_double(-1, 1);
|
||||||
|
auto r = std::sqrt(1 - z*z);
|
||||||
|
return Vec3(r*std::cos(a), r*std::sin(a), z);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3 random_in_hemisphere(const Vec3& normal) {
|
||||||
|
Vec3 in_unit_sphere = random_in_unit_sphere();
|
||||||
|
if (dot(in_unit_sphere, normal) > 0.0)
|
||||||
|
return in_unit_sphere;
|
||||||
|
else
|
||||||
|
return -in_unit_sphere;
|
||||||
|
}
|
25
vec3.h
25
vec3.h
@ -112,27 +112,14 @@ inline Vec3 unit_vector(Vec3 v) {
|
|||||||
return v / v.length();
|
return v / v.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 random_in_unit_sphere() {
|
inline Vec3 reflect(const Vec3& v, const Vec3& n) {
|
||||||
while (true) {
|
return v - 2 * dot(v, n) * n;
|
||||||
auto p = Vec3::random(-1, 1);
|
|
||||||
if (p.length_squared() >= 1) continue;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 random_unit_vector() {
|
Vec3 random_in_unit_sphere();
|
||||||
auto a = random_double(0, 2*pi);
|
|
||||||
auto z = random_double(-1, 1);
|
|
||||||
auto r = std::sqrt(1 - z*z);
|
|
||||||
return Vec3(r*std::cos(a), r*std::sin(a), z);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3 random_in_hemisphere(const Vec3& normal) {
|
Vec3 random_unit_vector();
|
||||||
Vec3 in_unit_sphere = random_in_unit_sphere();
|
|
||||||
if (dot(in_unit_sphere, normal) > 0.0)
|
Vec3 random_in_hemisphere(const Vec3& normal);
|
||||||
return in_unit_sphere;
|
|
||||||
else
|
|
||||||
return -in_unit_sphere;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // VEC3_H
|
#endif // VEC3_H
|
||||||
|
20
wtracer.cpp
20
wtracer.cpp
@ -17,10 +17,11 @@ Color ray_color(const Ray& r, const Hittable& world, int depth) {
|
|||||||
return Color(0, 0, 0);
|
return Color(0, 0, 0);
|
||||||
|
|
||||||
if (world.hit(r, 0.001, infinity, rec)) {
|
if (world.hit(r, 0.001, infinity, rec)) {
|
||||||
//Point3 target = rec.p + rec.normal + random_in_unit_sphere();
|
Ray scattered;
|
||||||
//Point3 target = rec.p + rec.normal + random_unit_vector();
|
Color attenuation;
|
||||||
Point3 target = rec.p + random_in_hemisphere(rec.normal);
|
if (rec.mat_ptr->scatter(r, rec, attenuation, scattered))
|
||||||
return 0.5 * ray_color(Ray(rec.p, target - rec.p), world, depth-1);
|
return attenuation * ray_color(scattered, world, depth - 1);
|
||||||
|
return Color(0, 0, 0);
|
||||||
}
|
}
|
||||||
Vec3 unit_direction = unit_vector(r.direction());
|
Vec3 unit_direction = unit_vector(r.direction());
|
||||||
auto t = 0.5 * (unit_direction.y() + 1.0);
|
auto t = 0.5 * (unit_direction.y() + 1.0);
|
||||||
@ -33,14 +34,21 @@ int main() {
|
|||||||
const int image_width = 768;
|
const int image_width = 768;
|
||||||
//const int image_width = 384;
|
//const int image_width = 384;
|
||||||
const int image_height = static_cast<int>(image_width / aspect_ratio);
|
const int image_height = static_cast<int>(image_width / aspect_ratio);
|
||||||
|
//const int samples_per_pixel = 1000;
|
||||||
const int samples_per_pixel = 400;
|
const int samples_per_pixel = 400;
|
||||||
const int max_depth = 50;
|
const int max_depth = 50;
|
||||||
|
|
||||||
std::cout << "P3\n" << image_width << " " << image_height << "\n255\n";
|
std::cout << "P3\n" << image_width << " " << image_height << "\n255\n";
|
||||||
|
|
||||||
Hittable_list world;
|
Hittable_list world;
|
||||||
world.add(std::make_shared<Sphere>(Point3(0, 0, -1), 0.5));
|
/*world.add(std::make_shared<Sphere>(Point3(0, 0, -1), 0.5));
|
||||||
world.add(std::make_shared<Sphere>(Point3(0, -100.5, -1), 100));
|
world.add(std::make_shared<Sphere>(Point3(0, -100.5, -1), 100));*/
|
||||||
|
|
||||||
|
world.add(std::make_shared<Sphere>(Point3(0, 0, -1), 0.5, std::make_shared<Lambertian>(Color(0.7, 0.3, 0.3))));
|
||||||
|
world.add(std::make_shared<Sphere>(Point3(0, -100.5, -1), 100, std::make_shared<Lambertian>(Color(0.8, 0.8, 0.8))));
|
||||||
|
|
||||||
|
world.add(std::make_shared<Sphere>(Point3(1, 0, -1), 0.5, std::make_shared<Metal>(Color(0.8, 0.6, 0.2))));
|
||||||
|
world.add(std::make_shared<Sphere>(Point3(-1, 0, -1), 0.5, std::make_shared<Metal>(Color(0.8, 0.8, 0.8))));
|
||||||
|
|
||||||
Camera cam;
|
Camera cam;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user