#include #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 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; }