Add possibility to play with focal length and aperture to the camera. Not enabled by default.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user