Skip to content

Commit

Permalink
Added support for rendering diffuse area lights
Browse files Browse the repository at this point in the history
  • Loading branch information
Pedro Jorquera committed Mar 25, 2024
1 parent e4afc36 commit 71fbf19
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 18 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ A simple C++ Raytracer based on "Ray Tracing in One Weekend" book.

![render image with motion blur](docs/render-motion-blur.png)

![render image with marble textyre](docs/render-marble.png)
![render image with marble texture](docs/render-marble.png)

![render image with diffuse light](docs/render-light.png)

## Features

Expand All @@ -25,6 +27,7 @@ A simple C++ Raytracer based on "Ray Tracing in One Weekend" book.
* Motion blur.
* Checked textures.
* Perlin noise based textures.
* Diffuse area light.

## Building

Expand Down
Binary file added docs/render-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 18 additions & 13 deletions src/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,34 @@

using namespace std;

inline Color background(const Ray& ray) {
Color Camera::background(const Ray& ray) {
/*
auto unitDir = ray.dir().unit();
auto a = 0.5 * (unitDir.y() + 1.0);
return (1.0 - a) * Color(1.0, 1.0, 1.0) + a * Color(0.5, 0.7, 1.0);
*/
return _background;
}

inline Color color(const Ray& ray, int depth, const shared_ptr<const Intersectable>& intersectable) {
Color Camera::color(const Ray& ray, int depth, const shared_ptr<const Intersectable>& intersectable) {
if (depth <= 0) return Color(0.0, 0.0, 0.0);
Hit hit;
if (intersectable->intersects(ray, Interval(0.001), hit)) {
Ray scattered;
Color attenuation;
if (hit.material()->scatter(ray, hit, attenuation, scattered))
return attenuation * color(scattered, depth - 1, intersectable);
return Color(0,0,0);
}

return background(ray);
if (!intersectable->intersects(ray, Interval(0.001), hit)) return background(ray);

Ray scattered;
Color attenuation;
Color color_from_emission = hit.material()->emitted(hit.u(), hit.v(), hit.point());

if (!hit.material()->scatter(ray, hit, attenuation, scattered)) return color_from_emission;

Color color_from_scatter = attenuation * color(scattered, depth - 1, intersectable);

return color_from_emission + color_from_scatter;
}

Camera::Camera(double aspect, int samplesPerPixel,
int maxDepth, int imageWidth, double vfov, Vector lookFrom, Vector lookAt, Vector vup, double defocusAngle, double focusDist): _aspect(aspect), _samplesPerPixel(samplesPerPixel), _maxDepth(maxDepth), _lookFrom(lookFrom),
_lookAt(lookAt), _vup(vup), _defocusAngle(defocusAngle), _focusDist(focusDist)
int maxDepth, int imageWidth, double vfov, Vector lookFrom, Vector lookAt, Vector vup, Color background, double defocusAngle, double focusDist): _aspect(aspect), _samplesPerPixel(samplesPerPixel), _maxDepth(maxDepth), _lookFrom(lookFrom),
_lookAt(lookAt), _vup(vup), _background(background), _defocusAngle(defocusAngle), _focusDist(focusDist)
{
auto imageHeight = int(imageWidth / aspect);
imageHeight = (imageHeight < 1) ? 1 : imageHeight;
Expand Down
5 changes: 5 additions & 0 deletions src/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class Camera {
Vector _defocusDiskU;
Vector _defocusDiskV;

Color _background;

Point defocusDiskSample() {
auto p = Vector::randomInUnitDisc();
return _lookFrom + (p.x() * _defocusDiskU) + (p.y() * _defocusDiskV);
Expand All @@ -50,12 +52,15 @@ class Camera {
Vector lookFrom = Vector(13.0, 2.0, 3.0),
Vector lookAt = Vector(0.0, 0.0, 0.0),
Vector vup = Vector(0.0, 1.0, 0.0),
Color background = Color(0.7, 0.8, 1.0),
double defocusAngle = 0.6,
double focusDist = 10.0);

double aspect() const { return _aspect; }
const Viewport& viewport() const { return _viewport; }

Color color(const Ray& ray, int depth, const std::shared_ptr<const Intersectable>& intersectable);
Color background(const Ray& ray);
void render(const std::shared_ptr<const Intersectable>& intersectable, const std::string& filename);

};
24 changes: 20 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void twoSpheres() {
scene->add(make_shared<Sphere>(Point(0.0, -10.0, 0.0), 10.0, make_shared<Lambertian>(checker)));
scene->add(make_shared<Sphere>(Point(0.0, 10.0, 0.0), 10.0, make_shared<Lambertian>(checker)));

Camera camera(16.0 / 9.0, 50, 50, 400, 20.0, Vector(13.0, 2.0, 3.0), Vector(0.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 0.0, 10.0);
Camera camera(16.0 / 9.0, 50, 50, 400, 20.0, Vector(13.0, 2.0, 3.0), Vector(0.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), Color(0.7, 0.8, 1.0), 0.0, 10.0);

camera.render(scene, "image.ppm");
}
Expand All @@ -80,7 +80,7 @@ void earth() {
shared_ptr<Scene> scene = make_shared<Scene>();
scene->add(globe);

Camera camera(16.0 / 9.0, 100, 50, 400, 20.0, Vector(0.0, 0.0, 12.0), Vector(0.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 0.0, 10.0);
Camera camera(16.0 / 9.0, 100, 50, 400, 20.0, Vector(0.0, 0.0, 12.0), Vector(0.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), Color(0.7, 0.8, 1.0), 0.0, 10.0);

camera.render(scene, "image.ppm");
}
Expand Down Expand Up @@ -113,18 +113,34 @@ void quads() {
scene->add(make_shared<Quad>(Point(-2, 3, 1), Vector(4, 0, 0), Vector(0, 0, 4), upper_orange));
scene->add(make_shared<Quad>(Point(-2,-3, 5), Vector(4, 0, 0), Vector(0, 0,-4), lower_teal));

Camera camera(1.0, 100, 50, 400, 80.0, Vector(0, 0, 9), Vector(0, 0, 0), Vector(0.0, 1.0, 0.0), 0.0);
Camera camera(1.0, 100, 50, 400, 80.0, Vector(0, 0, 9), Vector(0, 0, 0), Vector(0.0, 1.0, 0.0), Color(0.7, 0.8, 1.0), 0.0);

camera.render(scene, "image.png");
}

void simple_light() {
shared_ptr<Scene> scene = make_shared<Scene>();

auto pertext = make_shared<NoiseTexture>(4);
scene->add(make_shared<Sphere>(Point(0.0, -1000.0, 0.0), 1000.0, make_shared<Lambertian>(pertext)));
scene->add(make_shared<Sphere>(Point(0.0, 2.0, 0.0), 2.0, make_shared<Lambertian>(pertext)));

auto difflight = make_shared<DiffuseLight>(Color(4.0, 4.0, 4.0));
scene->add(make_shared<Quad>(Point(3.0, 1.0, -2.0), Vector(2.0, 0.0, 0.0), Vector(0.0, 2.0, 0.0), difflight));

Camera camera(16.0 / 9.0, 500, 50, 1920, 20.0, Vector(26.0, 3.0, 6.0), Vector(0.0, 2.0, 0.0), Vector(0.0, 1.0, 0.0), Color(0.0, 0.0, 0.0), 0.0);

camera.render(scene, "image.png");
}

int main() {
switch (5) {
switch (6) {
case 1: randomSpheres(); break;
case 2: twoSpheres(); break;
case 3: earth(); break;
case 4: twoPerlinSpheres(); break;
case 5: quads(); break;
case 6: simple_light(); break;
}
return 0;
}
24 changes: 24 additions & 0 deletions src/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class Material {

virtual ~Material() = default;
virtual bool scatter(const Ray& ray, const Hit& hit, Color& attenuation, Ray& scattered) const = 0;
virtual Color emitted(double u, double v, const Point& point) const {
return Color(0.0, 0.0, 0.0);
}

};

Expand Down Expand Up @@ -89,3 +92,24 @@ class Dielectric : public Material {
}

};

class DiffuseLight : public Material {

private:

std::shared_ptr<Texture> _texture;

public:

DiffuseLight(const std::shared_ptr<Texture>& texture):_texture(texture) {}
DiffuseLight(const Color& color):_texture(std::make_shared<SolidColor>(color)) {}

bool scatter(const Ray &ray, const Hit &hit, Color &attenuation, Ray &scattered) const override {
return false;
}

Color emitted(double u, double v, const Point &point) const override {
return _texture->color(u, v, point);
}

};

0 comments on commit 71fbf19

Please sign in to comment.