Skip to content

Commit

Permalink
adding emissive light source
Browse files Browse the repository at this point in the history
  • Loading branch information
alysssssa committed May 8, 2023
1 parent e4af3e2 commit bb46e29
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 19 deletions.
2 changes: 1 addition & 1 deletion raytracer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ project(raytracer)

set(CMAKE_CXX_STANDARD 14)

add_executable(raytracer main.cpp vec3.h colour.h ray.h hittable.h sphere.h hittable_list.h raytracer.h camera.h material.h moving_sphere.h aabb.h bvh.h texture.h perlin.h)
add_executable(raytracer main.cpp vec3.h colour.h ray.h hittable.h sphere.h hittable_list.h raytracer.h camera.h material.h moving_sphere.h aabb.h bvh.h texture.h perlin.h aarect.h)
53 changes: 53 additions & 0 deletions raytracer/aarect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

#ifndef AARECT_H
#define AARECT_H

#include "raytracer.h"
#include "hittable.h"

class xy_rect : public hittable {
public:
xy_rect() {}

xy_rect(double _x0, double _x1, double _y0, double _y1, double _k, shared_ptr<material> mat) : x0(_x0), x1(_x1), y0(_y0), y1(_y1), k(_k), mp(mat) {};

virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const override;

virtual bool bounding_box(double time0, double time1, aabb& output_box) const override {
// The bounding box must have non-zero width in each dimension, so pad the Z
// dimension a small amount.
output_box = aabb(point3(x0, y0, k-0.0001), point3(x1, y1, k+0.0001));
return true;
}

public:
shared_ptr<material> mp;
double x0, x1, y0, y1, k;
};

bool xy_rect::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
auto t = (k - r.origin().z()) / r.direction().z();

if (t < t_min || t > t_max)
return false;

auto x = r.origin().x() + t*r.direction().x();
auto y = r.origin().y() + t*r.direction().y();

if (x < x0 || x > x1 || y < y0 || y > y1)
return false;

rec.u = (x-x0) / (x1-x0);
rec.v = (y-y0) / (y1-y0);
rec.t = t;

auto outward_normal = vec3(0, 0, 1);
rec.set_face_normal(r, outward_normal);
rec.mat_ptr = mp;
rec.p = r.at(t);

return true;
}


#endif // AARECT_H
60 changes: 42 additions & 18 deletions raytracer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "material.h"
#include "moving_sphere.h"
#include "bvh.h"
#include "aarect.h"

#include <iostream>

Expand All @@ -15,29 +16,26 @@
// 2. determine which objects the ray intersects
// 3. compute a colour for that intersection point

colour ray_colour(const ray& r, const hittable& world, int depth) {
colour ray_colour(const ray& r, const colour& background, const hittable& world, int depth) {
hit_record rec;

// limit the maximum recursion depth, returning no light contribution at the maximum depth
if (depth <= 0)
return {0,0,0};

// generating a random diffuse bounce ray from hit point to random point (on the unit sphere from center p+n)
// if the ray hits nothing, return the background colour
// shadow acne: ignore hits very near zero (t_min = 0.001)
if (world.hit(r, 0.001, infinity, rec)) {
ray scattered;
colour attenuation;
if (rec.mat_ptr->scatter(r, rec, attenuation, scattered))
return attenuation * ray_colour(scattered, world, depth-1);
return {0,0,0};
}
if (!world.hit(r, 0.001, infinity, rec))
return background;

ray scattered;
colour attenuation;
colour emitted = rec.mat_ptr->emitted(rec.u, rec.v, rec.p);

// return colour of the background
vec3 unit_direction = unit_vector(r.direction());
auto t = 0.5*(unit_direction.y() + 1.0);
// linear interpolation between white (t=0) and blue (t=1)
// blended_value = (1-t)*start_value + t*end_value
return (1.0-t)*colour(1.0, 1.0, 1.0) + t*colour(0.5, 0.7, 1.0);
if (!rec.mat_ptr->scatter(r, rec, attenuation, scattered))
return emitted;

return emitted + attenuation * ray_colour(scattered, background, world, depth-1);
}

hittable_list random_scene() {
Expand Down Expand Up @@ -119,13 +117,27 @@ hittable_list earth() {
return {globe};
}

hittable_list simple_light() {
hittable_list objects;

auto pertext = make_shared<noise_texture>(2);
objects.add(make_shared<sphere>(point3(0,-1000,0), 1000, make_shared<lambertian>(pertext)));
objects.add(make_shared<sphere>(point3(0,2,0), 2, make_shared<lambertian>(pertext)));

// light is brighter than (1,1,1) to allow it to be bright enough to light things
auto difflight = make_shared<diffuse_light>(colour(4,4,4));
objects.add(make_shared<xy_rect>(3, 5, 1, 3, -2, difflight));

return objects;
}

int main() {

// write output image in ppm
const auto aspect_ratio = 16.0 / 9.0;
const int image_width = 400;
const int image_height = static_cast<int>(image_width / aspect_ratio);
const int samples_per_pixel = 50;
const int samples_per_pixel = 400;
const int max_depth = 50;

// world
Expand All @@ -135,10 +147,12 @@ int main() {
point3 lookat;
auto vfov = 40.0;
auto aperture = 0.0;
colour background(0,0,0);

switch (0) {
case 1:
world = random_scene();
background = colour(0.70, 0.80, 1.00);
lookfrom = point3(13,2,3);
lookat = point3(0,0,0);
vfov = 20.0;
Expand All @@ -147,26 +161,36 @@ int main() {

case 2:
world = two_spheres();
background = colour(0.70, 0.80, 1.00);
lookfrom = point3(13,2,3);
lookat = point3(0,0,0);
vfov = 20.0;
break;

case 3:
world = two_perlin_spheres();
background = colour(0.70, 0.80, 1.00);
lookfrom = point3(13,2,3);
lookat = point3(0,0,0);
vfov = 20.0;
break;

default:
case 4:
world = earth();
background = colour(0.70, 0.80, 1.00);
lookfrom = point3(13,2,3);
lookat = point3(0,0,0);
vfov = 20.0;
break;

default:
case 5:
background = colour(0,0,0);
world = simple_light();
lookfrom = point3(26,3,6);
lookat = point3(0,2,0);
vfov = 20.0;
break;
}

// camera with depth of field
Expand All @@ -189,7 +213,7 @@ int main() {
auto u = (i + random_double()) / (image_width-1);
auto v = (j + random_double()) / (image_height-1);
ray r = cam.get_ray(u, v);
pixel_colour += ray_colour(r, world, max_depth);
pixel_colour += ray_colour(r, background, world, max_depth);
}
write_colour(std::cout, pixel_colour, samples_per_pixel);
}
Expand Down
23 changes: 23 additions & 0 deletions raytracer/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class material {
virtual bool scatter(
const ray& r_in, const hit_record& rec, colour& attenuation, ray& scattered
) const = 0;

virtual colour emitted(double u, double v, const point3& p) const {
return {0,0,0};
}
};

class lambertian : public material {
Expand Down Expand Up @@ -99,4 +103,23 @@ class dielectric : public material {

};

class diffuse_light : public material {
public:
explicit diffuse_light(shared_ptr<texture> a) : emit(a) {}
explicit diffuse_light(colour c) : emit(make_shared<solid_colour>(c)) {}

virtual bool scatter(
const ray& r_in, const hit_record& rec, colour& attenuation, ray& scattered
) const override {
return false;
}

virtual colour emitted(double u, double v, const point3& p) const override {
return emit->value(u, v, p);
}

public:
shared_ptr<texture> emit;
};

#endif // MATERIAL_H

0 comments on commit bb46e29

Please sign in to comment.