Adding materials: solid color and checkered.
This commit is contained in:
parent
351bbcfe87
commit
bd704eb6ed
6
Makefile
6
Makefile
@ -2,15 +2,15 @@ CXX = g++
|
||||
|
||||
CXXFLAGS = -std=c++20 -Wall -Wextra -Wno-unused-parameter -march=native -O3 -flto -fopenmp
|
||||
|
||||
DEPS = util.h vec3.h color.h ray.h camera.h hittable.h hittable_list.h sphere.h material.h lodepng.h moving_sphere.h bvh.h aabb.h
|
||||
OBJ = main.o material.o vec3.o lodepng.o moving_sphere.o bvh.o
|
||||
DEPS = util.h vec3.h color.h ray.h camera.h hittable.h hittable_list.h sphere.h material.h lodepng.h moving_sphere.h bvh.h aabb.h texture.h
|
||||
OBJ = main.o material.o vec3.o lodepng.o sphere.o moving_sphere.o bvh.o
|
||||
|
||||
TARGET = toytracer
|
||||
|
||||
all: $(TARGET) run
|
||||
|
||||
run: $(TARGET)
|
||||
time -f '%E elapsed' ./$(TARGET)
|
||||
time -f '%E elapsed %M Kb memory' ./$(TARGET)
|
||||
eog image.png
|
||||
|
||||
%.o: %.cpp $(DEPS)
|
||||
|
@ -14,6 +14,8 @@ struct hit_record {
|
||||
Vec3 normal;
|
||||
std::shared_ptr<Material> mat_ptr;
|
||||
double t;
|
||||
double u;
|
||||
double v;
|
||||
bool front_face;
|
||||
|
||||
inline void set_face_normal(const Ray& r, const Vec3& outward_normal) {
|
||||
|
42
main.cpp
42
main.cpp
@ -39,7 +39,12 @@ Color ray_color(const Ray& r, const Hittable& world, int depth) {
|
||||
Bvh_node setup_random_scene(const int sph_i) {
|
||||
Hittable_list world;
|
||||
|
||||
auto ground_material = std::make_shared<Lambertian>(Color(0.5, 0.5, 0.5));
|
||||
//auto ground_material = std::make_shared<Lambertian>(std::make_shared<Solid_color>(Color(0.5, 0.5, 0.5)));
|
||||
auto checker = std::make_shared<Checker_texture>(
|
||||
std::make_shared<Solid_color>(0.2, 0.3, 0.1),
|
||||
std::make_shared<Solid_color>(0.9, 0.9, 0.9)
|
||||
);
|
||||
auto ground_material = std::make_shared<Lambertian>(checker);
|
||||
world.add(std::make_shared<Sphere>(Point3(0, -1000, 0), 1000, ground_material));
|
||||
for (int a = -sph_i; a<sph_i; a++) {
|
||||
for (int b = -sph_i; b<sph_i; b++) {
|
||||
@ -51,14 +56,14 @@ Bvh_node setup_random_scene(const int sph_i) {
|
||||
if (choose_mat < 0.2) {
|
||||
// diffuse moving
|
||||
auto albedo = Color::random() * Color::random();
|
||||
sphere_material = std::make_shared<Lambertian>(albedo);
|
||||
auto center2 = center + Vec3(0, random_double(0, 0.5), 0);
|
||||
sphere_material = std::make_shared<Lambertian>(std::make_shared<Solid_color>(albedo));
|
||||
auto center2 = center + Vec3(0, random_double(0, 0.1), 0);
|
||||
world.add(std::make_shared<Moving_sphere>(center, center2, 0.0, 1.0, 0.2, sphere_material));
|
||||
}
|
||||
if (choose_mat < 0.7) {
|
||||
else if (choose_mat < 0.7) {
|
||||
// diffuse
|
||||
auto albedo = Color::random() * Color::random();
|
||||
sphere_material = std::make_shared<Lambertian>(albedo);
|
||||
sphere_material = std::make_shared<Lambertian>(std::make_shared<Solid_color>(albedo));
|
||||
world.add(std::make_shared<Sphere>(center, 0.2, sphere_material));
|
||||
} else if (choose_mat < 0.95) {
|
||||
// metal
|
||||
@ -79,7 +84,7 @@ Bvh_node setup_random_scene(const int sph_i) {
|
||||
auto material1 = std::make_shared<Dielectric>(1.45);
|
||||
world.add(std::make_shared<Sphere>(Point3(0, 1, 0), 1.0, material1));
|
||||
|
||||
auto material2 = std::make_shared<Lambertian>(Color(0.4, 0.2, 0.1));
|
||||
auto material2 = std::make_shared<Lambertian>(std::make_shared<Solid_color>(Color(0.4, 0.2, 0.1)));
|
||||
world.add(std::make_shared<Sphere>(Point3(-4, 1, 0), 1.0, material2));
|
||||
|
||||
auto material3 = std::make_shared<Metal>(Color(0.7, 0.6, 0.5), 0.0);
|
||||
@ -88,6 +93,22 @@ Bvh_node setup_random_scene(const int sph_i) {
|
||||
return world.generate_bvh(0, 1);
|
||||
}
|
||||
|
||||
Hittable_list two_spheres() {
|
||||
Hittable_list objects;
|
||||
|
||||
auto checker = std::make_shared<Checker_texture>(
|
||||
std::make_shared<Solid_color>(0.2, 0.3, 0.1),
|
||||
std::make_shared<Solid_color>(0.9, 0.9, 0.9)
|
||||
);
|
||||
|
||||
auto mat = std::make_shared<Lambertian>(checker);
|
||||
|
||||
objects.add(std::make_shared<Sphere>(Point3(0, -10, 0), 10, mat));
|
||||
objects.add(std::make_shared<Sphere>(Point3(0, 10, 0), 10, mat));
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
struct render_tile {
|
||||
int start_x;
|
||||
int start_y;
|
||||
@ -107,8 +128,8 @@ int main() {
|
||||
const int samples_per_pixel = 400;
|
||||
const int max_depth = 50;
|
||||
|
||||
//const int tile_size = 128;
|
||||
const int tile_size = 64;
|
||||
const int tile_size = 128;
|
||||
//const int tile_size = 64;
|
||||
|
||||
//const int sph_i = 3;
|
||||
//const int sph_i = 5;
|
||||
@ -116,14 +137,15 @@ int main() {
|
||||
//const int sph_i = 11;
|
||||
|
||||
auto world = setup_random_scene(sph_i);
|
||||
//auto world = two_spheres();
|
||||
|
||||
Point3 lookfrom(13, 2, 3);
|
||||
Point3 lookat(0, 0, 0);
|
||||
Vec3 vup(0, 1, 0);
|
||||
//auto dist_to_focus = (lookfrom - lookat).length();
|
||||
auto dist_to_focus = 10;
|
||||
//auto aperture = 0.1;
|
||||
auto aperture = 0.0;
|
||||
auto aperture = 0.1;
|
||||
//auto aperture = 0.0;
|
||||
|
||||
Camera cam(lookfrom, lookat, vup, 20, aspect_ratio, aperture, dist_to_focus, 0.0, 1.0);
|
||||
|
||||
|
@ -7,7 +7,7 @@ bool Lambertian::scatter(const Ray& r_in, const hit_record& rec, Color& attenuat
|
||||
Vec3 scatter_direction = rec.normal + random_unit_vector();
|
||||
//Vec3 scatter_direction = random_in_hemisphere(rec.normal);
|
||||
scattered = Ray(rec.p, scatter_direction, r_in.time());
|
||||
attenuation = albedo;
|
||||
attenuation = albedo->value(rec.u, rec.v, rec.p);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "hittable.h"
|
||||
#include "vec3.h"
|
||||
#include "texture.h"
|
||||
|
||||
struct hit_record;
|
||||
|
||||
@ -13,12 +14,12 @@ public:
|
||||
|
||||
class Lambertian : public Material {
|
||||
public:
|
||||
Lambertian(const Color& a) : albedo(a) {}
|
||||
Lambertian(std::shared_ptr<Texture> a) : albedo(a) {}
|
||||
|
||||
virtual bool scatter(const Ray& r_in, const hit_record& rec, Color& attenuation, Ray& scattered) const;
|
||||
|
||||
private:
|
||||
Color albedo;
|
||||
std::shared_ptr<Texture> albedo;
|
||||
};
|
||||
|
||||
class Metal : public Material {
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "moving_sphere.h"
|
||||
#include "sphere.h"
|
||||
|
||||
Point3 Moving_sphere::center(double time) const {
|
||||
return center0 + ((time - time0) / (time1 - time0)) * (center1 - center0);
|
||||
}
|
||||
|
||||
bool Moving_sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) const {
|
||||
compute_sphere_uv((rec.p - center(r.time()))/radius, rec.u, rec.v);
|
||||
Vec3 oc = r.origin() - center(r.time());
|
||||
auto a = r.direction().length_squared();
|
||||
auto half_b = dot(oc, r.direction());
|
||||
|
39
sphere.cpp
Normal file
39
sphere.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "sphere.h"
|
||||
|
||||
bool Sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) const {
|
||||
compute_sphere_uv((rec.p - center)/radius, rec.u, rec.v);
|
||||
Vec3 oc = r.origin() - center;
|
||||
auto a = r.direction().length_squared();
|
||||
auto half_b = dot(oc, r.direction());
|
||||
auto c = oc.length_squared() - radius * radius;
|
||||
auto discriminant = half_b*half_b - a*c;
|
||||
if (discriminant > 0) {
|
||||
auto root = std::sqrt(discriminant);
|
||||
auto temp = (-half_b - root) / a;
|
||||
if (temp < tmax && temp > tmin) {
|
||||
rec.t = temp;
|
||||
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;
|
||||
}
|
||||
temp = (-half_b + root) / a;
|
||||
if (temp < tmax && temp > tmin) {
|
||||
rec.t = temp;
|
||||
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;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sphere::bounding_box(double t0, double t1, Aabb& output_box) const {
|
||||
output_box = Aabb(
|
||||
center - Vec3(radius, radius, radius),
|
||||
center + Vec3(radius, radius, radius));
|
||||
return true;
|
||||
}
|
42
sphere.h
42
sphere.h
@ -7,6 +7,7 @@
|
||||
#include "hittable.h"
|
||||
#include "material.h"
|
||||
#include "vec3.h"
|
||||
#include "util.h"
|
||||
|
||||
class Sphere : public Hittable {
|
||||
public:
|
||||
@ -22,42 +23,11 @@ private:
|
||||
std::shared_ptr<Material> mat_ptr;
|
||||
};
|
||||
|
||||
bool Sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) const {
|
||||
Vec3 oc = r.origin() - center;
|
||||
auto a = r.direction().length_squared();
|
||||
auto half_b = dot(oc, r.direction());
|
||||
auto c = oc.length_squared() - radius * radius;
|
||||
auto discriminant = half_b*half_b - a*c;
|
||||
if (discriminant > 0) {
|
||||
auto root = std::sqrt(discriminant);
|
||||
auto temp = (-half_b - root) / a;
|
||||
if (temp < tmax && temp > tmin) {
|
||||
rec.t = temp;
|
||||
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;
|
||||
}
|
||||
temp = (-half_b + root) / a;
|
||||
if (temp < tmax && temp > tmin) {
|
||||
rec.t = temp;
|
||||
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;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
inline void compute_sphere_uv(const Vec3& p, double& u, double& v) {
|
||||
auto phi = std::atan2(p.z(), p.x());
|
||||
auto theta = asin(p.y());
|
||||
u = 1 - (phi + pi) / (2 * pi);
|
||||
v = (theta + pi/2) / pi;
|
||||
}
|
||||
|
||||
bool Sphere::bounding_box(double t0, double t1, Aabb& output_box) const {
|
||||
output_box = Aabb(
|
||||
center - Vec3(radius, radius, radius),
|
||||
center + Vec3(radius, radius, radius));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif // SPHERE_H
|
||||
|
46
texture.h
Normal file
46
texture.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef TEXTURE_H
|
||||
#define TEXTURE_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "vec3.h"
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
virtual Color value(double u, double v, const Point3& p) const = 0;
|
||||
};
|
||||
|
||||
class Solid_color : public Texture {
|
||||
public:
|
||||
Solid_color() {}
|
||||
Solid_color(Color c) : color_value(c) {}
|
||||
|
||||
Solid_color(double red, double green, double blue)
|
||||
: Solid_color(Color(red, green, blue)) {}
|
||||
|
||||
virtual Color value(double u, double v, const Vec3& p) const {
|
||||
return color_value;
|
||||
}
|
||||
|
||||
private:
|
||||
Color color_value;
|
||||
};
|
||||
|
||||
class Checker_texture : public Texture {
|
||||
public:
|
||||
Checker_texture() {}
|
||||
Checker_texture(std::shared_ptr<Texture> t0, std::shared_ptr<Texture> t1) : even(t0), odd(t1) {}
|
||||
|
||||
virtual Color value(double u, double v, const Vec3& p) const {
|
||||
auto sines = std::sin(10*p.x())*std::sin(10*p.y())*std::sin(10*p.z());
|
||||
if (sines < 0)
|
||||
return odd->value(u, v, p);
|
||||
else
|
||||
return even->value(u, v, p);
|
||||
}
|
||||
private:
|
||||
std::shared_ptr<Texture> even;
|
||||
std::shared_ptr<Texture> odd;
|
||||
};
|
||||
|
||||
#endif // TEXTURE_H
|
3
util.h
3
util.h
@ -14,7 +14,8 @@ inline double degrees_to_radians(double degrees) {
|
||||
|
||||
inline double random_double() {
|
||||
static std::uniform_real_distribution<double> distribution(0.0, 1.0);
|
||||
static std::mt19937 generator(std::time(nullptr));
|
||||
//static std::mt19937 generator(std::time(nullptr));
|
||||
static std::mt19937 generator(std::random_device{}());
|
||||
return distribution(generator);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user