cloudy-raytracer/shader/depthoffieldshader.cpp

47 lines
1.7 KiB
C++

#include <iostream>
#include "depthoffieldshader.h"
DOFShader::DOFShader(SimpleScene& _scene, Color const &_diffuseColor, int _numSamples, float _aperture, float _focalDistance, float _focalLength, PerspectiveCamera& _camera) : scene(_scene), diffuseColor(_diffuseColor), numSamples(_numSamples), aperture(_aperture),
focalDistance(_focalDistance), focalLength(_focalLength), camera(_camera) {}
std::random_device DOFShader::rd;
std::mt19937 DOFShader::gen(DOFShader::rd());
Color DOFShader::shade(Scene const &scene, Ray const &ray) const {
Color color;
// Accumulate the light over all light sources
for (const auto &light : scene.lights()) {
Light::Illumination const illum = light->illuminate(scene, ray);
Color const diffuse = this->diffuseColor * std::max(dotProduct(-illum.direction, ray.normal), 0.0f);
// Add the sample color to the final color
color += diffuse * sample(ray, illum);
}
return color;
}
Color DOFShader::sample(Ray ray, Light::Illumination const &illum) const {
std::uniform_real_distribution<float> dis(-1.0, 1.0);
// calculate the point of focus
Vector3d focusPoint = ray.origin + ray.direction * focalDistance;
// create a random point on the aperture
Vector3d rnd = Vector3d(dis(gen), dis(gen), 0);
Vector3d offset = aperture * (rnd.x * camera.getRightDirection() + rnd.y * camera.getUpDirection());
// create the new ray with the offset point
Vector3d dofRayStart = camera.getPosition() + offset;
Vector3d dofRayDir = normalized(focusPoint - (camera.getPosition() + offset));
Ray dofRay = Ray(dofRayStart, dofRayDir);
// trace the new ray and sample the color
Color tracedColor = scene.traceRay(dofRay);
return tracedColor;
}