47 lines
1.7 KiB
C++
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;
|
|
}
|