Skip to content

Commit

Permalink
adding more spheres to the scene; rudimentary materials
Browse files Browse the repository at this point in the history
  • Loading branch information
ssloy committed Jan 20, 2019
1 parent 5806eb4 commit c19c430
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
Binary file modified out.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 40 additions & 9 deletions tinyraytracer.cpp
Expand Up @@ -5,11 +5,18 @@
#include <vector>
#include "geometry.h"

struct Material {
Material(const Vec3f &color) : diffuse_color(color) {}
Material() : diffuse_color() {}
Vec3f diffuse_color;
};

struct Sphere {
Vec3f center;
float radius;
Material material;

Sphere(const Vec3f &c, const float &r) : center(c), radius(r) {}
Sphere(const Vec3f &c, const float &r, const Material &m) : center(c), radius(r), material(m) {}

bool ray_intersect(const Vec3f &orig, const Vec3f &dir, float &t0) const {
Vec3f L = center - orig;
Expand All @@ -25,16 +32,32 @@ struct Sphere {
}
};

Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const Sphere &sphere) {
float sphere_dist = std::numeric_limits<float>::max();
if (!sphere.ray_intersect(orig, dir, sphere_dist)) {
bool scene_intersect(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &spheres, Vec3f &hit, Vec3f &N, Material &material) {
float spheres_dist = std::numeric_limits<float>::max();
for (size_t i=0; i < spheres.size(); i++) {
float dist_i;
if (spheres[i].ray_intersect(orig, dir, dist_i) && dist_i < spheres_dist) {
spheres_dist = dist_i;
hit = orig + dir*dist_i;
N = (hit - spheres[i].center).normalize();
material = spheres[i].material;
}
}
return spheres_dist<1000;
}

Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &spheres) {
Vec3f point, N;
Material material;

if (!scene_intersect(orig, dir, spheres, point, N, material)) {
return Vec3f(0.2, 0.7, 0.8); // background color
}

return Vec3f(0.4, 0.4, 0.3);
return material.diffuse_color;
}

void render(const Sphere &sphere) {
void render(const std::vector<Sphere> &spheres) {
const int width = 1024;
const int height = 768;
const int fov = M_PI/2.;
Expand All @@ -46,7 +69,7 @@ void render(const Sphere &sphere) {
float x = (2*(i + 0.5)/(float)width - 1)*tan(fov/2.)*width/(float)height;
float y = -(2*(j + 0.5)/(float)height - 1)*tan(fov/2.);
Vec3f dir = Vec3f(x, y, -1).normalize();
framebuffer[i+j*width] = cast_ray(Vec3f(0,0,0), dir, sphere);
framebuffer[i+j*width] = cast_ray(Vec3f(0,0,0), dir, spheres);
}
}

Expand All @@ -62,8 +85,16 @@ void render(const Sphere &sphere) {
}

int main() {
Sphere sphere(Vec3f(-3, 0, -16), 2);
render(sphere);
Material ivory(Vec3f(0.4, 0.4, 0.3));
Material red_rubber(Vec3f(0.3, 0.1, 0.1));

std::vector<Sphere> spheres;
spheres.push_back(Sphere(Vec3f(-3, 0, -16), 2, ivory));
spheres.push_back(Sphere(Vec3f(-1.0, -1.5, -12), 2, red_rubber));
spheres.push_back(Sphere(Vec3f( 1.5, -0.5, -18), 3, red_rubber));
spheres.push_back(Sphere(Vec3f( 7, 5, -18), 4, ivory));

render(spheres);

return 0;
}
Expand Down

2 comments on commit c19c430

@tpaschalis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for anyone silly like me, if spheres appear to be 'drawn' in different order, depending on when they were initialized, here's what probably happens.
dist_i gets passed as t0, and changes value inside that function (much like material).
Be careful with what you're passing in functions (addresses or values?). The problem arose when writing this in Go.

@roaming-debug
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for anyone stupid like me, dist_i < spheres_dist in line 39 and spheres_dist = dist_i in line 40 make sure that the sphere closest to the camera will be drawn. Also, return spheres_dist<1000 in line 46 guarantees that the sphere a) father than 1000 from the camera, b) doesn't intersect with the ray will not be drawn

Please sign in to comment.