Add possibility to play with focal length and aperture to the camera. Not enabled by default.

This commit is contained in:
Godzil
2020-03-17 00:23:16 +00:00
parent 9849c16f66
commit 61ce9d3543
4 changed files with 36 additions and 9 deletions

View File

@@ -15,10 +15,11 @@
#include <stdio.h> #include <stdio.h>
#include <renderstat.h> #include <renderstat.h>
Camera::Camera(uint32_t hsize, uint32_t vsize, double fov) : verticalSize(vsize), horizontalSize(hsize), fieldOfView(fov) Camera::Camera(uint32_t hsize, uint32_t vsize, double fov, double focal, double aperture, uint32_t rayCount) : verticalSize(vsize),
horizontalSize(hsize), fieldOfView(fov), focalDistance(focal), apertureSize(aperture), rayCount(rayCount)
{ {
double aspectRatio = (double)hsize / (double)vsize; double aspectRatio = (double)hsize / (double)vsize;
double halfView = tan(fov / 2.0); double halfView = tan(fov / 2.0) * this->focalDistance;
if (aspectRatio >= 1) if (aspectRatio >= 1)
{ {
@@ -42,7 +43,7 @@ void Camera::setTransform(Matrix transform)
this->inverseTransform = transform.inverse(); this->inverseTransform = transform.inverse();
} }
Ray Camera::rayForPixel(uint32_t pixelX, uint32_t pixelY) Ray Camera::rayForPixel(uint32_t pixelX, uint32_t pixelY, double horzOffset, double vertOffset)
{ {
double xOffset = ((double)pixelX + 0.5) * this->pixelSize; double xOffset = ((double)pixelX + 0.5) * this->pixelSize;
double yOffset = ((double)pixelY + 0.5) * this->pixelSize; double yOffset = ((double)pixelY + 0.5) * this->pixelSize;
@@ -50,8 +51,8 @@ Ray Camera::rayForPixel(uint32_t pixelX, uint32_t pixelY)
double worldX = this->halfWidth - xOffset; double worldX = this->halfWidth - xOffset;
double worldY = this->halfHeight - yOffset; double worldY = this->halfHeight - yOffset;
Tuple pixel = this->inverseTransform * Point(worldX, worldY, -1); Tuple pixel = this->inverseTransform * Point(worldX, worldY, -this->focalDistance);
Tuple origin = this->inverseTransform * Point(0, 0, 0); Tuple origin = this->inverseTransform * Point(horzOffset, vertOffset, 0);
Tuple direction = (pixel - origin).normalise(); Tuple direction = (pixel - origin).normalise();
stats.addCastedRay(); stats.addCastedRay();
@@ -70,9 +71,25 @@ Canvas Camera::render(World world, uint32_t depth)
{ {
for (x = 0 ; x < this->horizontalSize ; x++) for (x = 0 ; x < this->horizontalSize ; x++)
{ {
Ray r = this->rayForPixel(x, y); Tuple colour;
Tuple colour = world.colourAt(r, depth); if (this->apertureSize > 0)
{
int i;
for (i = 0 ; i < this->rayCount ; i++)
{
double horz = frandclip(-this->apertureSize/2, this->apertureSize / 2);
double vert = frandclip(-this->apertureSize/2, this->apertureSize / 2);
Ray r = this->rayForPixel(x, y, horz, vert);
colour = colour + world.colourAt(r, depth);
}
colour = colour / this->rayCount;
}
else
{
Ray r = this->rayForPixel(x, y);
colour = world.colourAt(r, depth);
}
stats.addPixel(); stats.addPixel();
image.putPixel(x, y, colour); image.putPixel(x, y, colour);
} }

View File

@@ -21,6 +21,10 @@ private:
double halfWidth; double halfWidth;
double halfHeight; double halfHeight;
public: public:
double focalDistance;
double apertureSize;
uint32_t rayCount;
uint32_t verticalSize; uint32_t verticalSize;
uint32_t horizontalSize; uint32_t horizontalSize;
double fieldOfView; double fieldOfView;
@@ -29,9 +33,9 @@ public:
Matrix inverseTransform; Matrix inverseTransform;
public: public:
Camera(uint32_t hsize, uint32_t vsize, double fov); Camera(uint32_t hsize, uint32_t vsize, double fov, double focal = 1, double aperture = 0, uint32_t rayCount = 1);
void setTransform(Matrix transform); void setTransform(Matrix transform);
Ray rayForPixel(uint32_t pixelX, uint32_t pixelY); Ray rayForPixel(uint32_t pixelX, uint32_t pixelY, double horzOffset = 0, double vertOffset = 0);
Canvas render(World w, uint32_t depth = 5); Canvas render(World w, uint32_t depth = 5);
}; };

View File

@@ -22,6 +22,7 @@ double min3(double a, double b, double c);
double max3(double a, double b, double c); double max3(double a, double b, double c);
double frand(); double frand();
double frandclip(double min, double max);
static double modulo(double a, double b) static double modulo(double a, double b)
{ {

View File

@@ -69,3 +69,8 @@ double frand()
{ {
return rand() / ((double) RAND_MAX); return rand() / ((double) RAND_MAX);
} }
double frandclip(double min, double max)
{
return (frand() * (max - min)) + min;
}