Commit 2e55bb3b authored by Jan Scheffczyk's avatar Jan Scheffczyk

Added biased lens sampling supported by input file through lenselements

parent 2fb7fe5a
......@@ -32,6 +32,7 @@
// cameras/perspective.cpp*
#include <filters/gaussian.h>
#include "cameras/perspective.h"
#include "paramset.h"
#include "sampler.h"
......@@ -41,13 +42,14 @@
namespace pbrt {
// PerspectiveCamera Method Definitions
PerspectiveCamera::PerspectiveCamera(const AnimatedTransform &CameraToWorld,
const Bounds2f &screenWindow,
Float shutterOpen, Float shutterClose,
Float lensRadius, Float focalDistance,
Float fov, Film *film,
const Medium *medium)
PerspectiveCamera::PerspectiveCamera(const AnimatedTransform &CameraToWorld, const Bounds2f &screenWindow, Float shutterOpen,
Float shutterClose, Float lensRadius, Float focalDistance, Float fov, Film *film,
const Medium *medium, int bokehType)
: ProjectiveCamera(CameraToWorld, Perspective(fov, 1e-2f, 1000.f),
screenWindow, shutterOpen, shutterClose, lensRadius,
focalDistance, film, medium) {
......@@ -64,6 +66,7 @@ PerspectiveCamera::PerspectiveCamera(const AnimatedTransform &CameraToWorld,
pMin /= pMin.z;
pMax /= pMax.z;
A = std::abs((pMax.x - pMin.x) * (pMax.y - pMin.y));
initBokeh(bokehType);
}
Float PerspectiveCamera::GenerateRay(const CameraSample &sample,
......@@ -74,9 +77,12 @@ Float PerspectiveCamera::GenerateRay(const CameraSample &sample,
Point3f pCamera = RasterToCamera(pFilm);
*ray = Ray(Point3f(0, 0, 0), Normalize(Vector3f(pCamera)));
// Modify ray for depth of field
// std::cout << lensRadius<<std::endl;
if (lensRadius > 0) {
// Sample point on lens
Point2f pLens = lensRadius * ConcentricSampleDisk(sample.pLens);
Point2f pLens = lensRadius * biasSample(sample);
// pLens= Point2f(1-pLens.x*pLens.x,1-pLens.y*pLens.y);
// Compute point on plane of focus
Float ft = focalDistance / ray->d.z;
......@@ -103,9 +109,9 @@ Float PerspectiveCamera::GenerateRayDifferential(const CameraSample &sample,
// Modify ray for depth of field
if (lensRadius > 0) {
// Sample point on lens
Point2f pLens = lensRadius * ConcentricSampleDisk(sample.pLens);
// Compute point on plane of focus
Point2f pLens = lensRadius * biasSample(sample);
pLens *= lensRadius;
// Compute point on plane of focus
Float ft = focalDistance / ray->d.z;
Point3f pFocus = (*ray)(ft);
......@@ -119,7 +125,7 @@ Float PerspectiveCamera::GenerateRayDifferential(const CameraSample &sample,
// Compute _PerspectiveCamera_ ray differentials accounting for lens
// Sample point on lens
Point2f pLens = lensRadius * ConcentricSampleDisk(sample.pLens);
Point2f pLens = lensRadius * biasSample(sample);
Vector3f dx = Normalize(Vector3f(pCamera + dxCamera));
Float ft = focalDistance / dx.z;
Point3f pFocus = Point3f(0, 0, 0) + (ft * dx);
......@@ -263,13 +269,18 @@ PerspectiveCamera *CreatePerspectiveCamera(const ParamSet &params,
} else
Error("\"screenwindow\" should have four values");
}
Float fov = params.FindOneFloat("fov", 90.);
Float halffov = params.FindOneFloat("halffov", -1.f);
int edges = params.FindOneInt("lenselements", 0);
if (halffov > 0.f)
// hack for structure synth, which exports half of the full fov
fov = 2.f * halffov;
return new PerspectiveCamera(cam2world, screen, shutteropen, shutterclose,
lensradius, focaldistance, fov, film, medium);
return new PerspectiveCamera(cam2world, screen, shutteropen, shutterclose, lensradius, focaldistance, fov, film,
medium, edges);
}
} // namespace pbrt
......@@ -49,10 +49,9 @@ namespace pbrt {
class PerspectiveCamera : public ProjectiveCamera {
public:
// PerspectiveCamera Public Methods
PerspectiveCamera(const AnimatedTransform &CameraToWorld,
const Bounds2f &screenWindow, Float shutterOpen,
Float shutterClose, Float lensRadius, Float focalDistance,
Float fov, Film *film, const Medium *medium);
PerspectiveCamera(const AnimatedTransform &CameraToWorld, const Bounds2f &screenWindow, Float shutterOpen,
Float shutterClose, Float lensRadius, Float focalDistance, Float fov, Film *film,
const Medium *medium, int bokehType);
Float GenerateRay(const CameraSample &sample, Ray *) const;
Float GenerateRayDifferential(const CameraSample &sample,
RayDifferential *ray) const;
......
......@@ -680,7 +680,7 @@ Float RealisticCamera::GenerateRay(const CameraSample &sample, Ray *ray) const {
// Trace ray from _pFilm_ through lens system
Float exitPupilBoundsArea;
Point3f pRear = SampleExitPupil(Point2f(pFilm.x, pFilm.y), sample.pLens,
Point3f pRear = SampleExitPupil(Point2f(pFilm.x, pFilm.y), biasSample(sample),
&exitPupilBoundsArea);
Ray rFilm(pFilm, pRear - pFilm, Infinity,
Lerp(sample.time, shutterOpen, shutterClose));
......
......@@ -97,4 +97,19 @@ Spectrum Camera::Sample_Wi(const Interaction &ref, const Point2f &u,
return Spectrum(0.f);
}
void Camera::initBokeh(int cornerAmount) {
bokehOptions.amount=cornerAmount;
bokehOptions.step = 2 * Pi / cornerAmount;
bokehOptions.corners = std::unique_ptr<Point2f[]>(new Point2f[cornerAmount]);
float cur = Pi / 2.0f;
Point2f* cornerArray= new Point2f[cornerAmount];
for (int i = 0; i < cornerAmount; i++) {
bokehOptions.corners[i] = Point2f(std::cos(cur), std::sin(cur));
cur += bokehOptions.step;
}
}
} // namespace pbrt
......@@ -43,76 +43,158 @@
#include "geometry.h"
#include "transform.h"
#include "film.h"
#include "sampling.h"
namespace pbrt {
struct CameraSample {
Point2f pFilm;
Point2f pLens;
Float time;
Float random;
};
struct Bokeh {
// also used as type
int amount;
float step;
std::unique_ptr<Point2f[]> corners;
};
// Camera Declarations
class Camera {
public:
// Camera Interface
Camera(const AnimatedTransform &CameraToWorld, Float shutterOpen,
Float shutterClose, Film *film, const Medium *medium);
virtual ~Camera();
virtual Float GenerateRay(const CameraSample &sample, Ray *ray) const = 0;
virtual Float GenerateRayDifferential(const CameraSample &sample,
RayDifferential *rd) const;
virtual Spectrum We(const Ray &ray, Point2f *pRaster2 = nullptr) const;
virtual void Pdf_We(const Ray &ray, Float *pdfPos, Float *pdfDir) const;
virtual Spectrum Sample_Wi(const Interaction &ref, const Point2f &u,
Vector3f *wi, Float *pdf, Point2f *pRaster,
VisibilityTester *vis) const;
// Camera Public Data
AnimatedTransform CameraToWorld;
const Float shutterOpen, shutterClose;
Film *film;
const Medium *medium;
};
struct CameraSample {
Point2f pFilm;
Point2f pLens;
Float time;
};
inline std::ostream &operator<<(std::ostream &os, const CameraSample &cs) {
os << "[ pFilm: " << cs.pFilm << " , pLens: " << cs.pLens <<
StringPrintf(", time %f ]", cs.time);
return os;
}
class ProjectiveCamera : public Camera {
public:
// ProjectiveCamera Public Methods
ProjectiveCamera(const AnimatedTransform &CameraToWorld,
const Transform &CameraToScreen,
const Bounds2f &screenWindow, Float shutterOpen,
Float shutterClose, Float lensr, Float focald, Film *film,
const Medium *medium)
: Camera(CameraToWorld, shutterOpen, shutterClose, film, medium),
CameraToScreen(CameraToScreen) {
// Initialize depth of field parameters
lensRadius = lensr;
focalDistance = focald;
// Compute projective camera transformations
// Compute projective camera screen transformations
ScreenToRaster =
Scale(film->fullResolution.x, film->fullResolution.y, 1) *
Scale(1 / (screenWindow.pMax.x - screenWindow.pMin.x),
1 / (screenWindow.pMin.y - screenWindow.pMax.y), 1) *
Translate(Vector3f(-screenWindow.pMin.x, -screenWindow.pMax.y, 0));
RasterToScreen = Inverse(ScreenToRaster);
RasterToCamera = Inverse(CameraToScreen) * RasterToScreen;
class Camera {
public:
// Camera Interface
Camera(const AnimatedTransform &CameraToWorld, Float shutterOpen,
Float shutterClose, Film *film, const Medium *medium);
virtual ~Camera();
virtual Float GenerateRay(const CameraSample &sample, Ray *ray) const = 0;
virtual Float GenerateRayDifferential(const CameraSample &sample,
RayDifferential *rd) const;
virtual Spectrum We(const Ray &ray, Point2f *pRaster2 = nullptr) const;
virtual void Pdf_We(const Ray &ray, Float *pdfPos, Float *pdfDir) const;
virtual Spectrum Sample_Wi(const Interaction &ref, const Point2f &u,
Vector3f *wi, Float *pdf, Point2f *pRaster,
VisibilityTester *vis) const;
// Camera Public Data
AnimatedTransform CameraToWorld;
const Float shutterOpen, shutterClose;
Film *film;
const Medium *medium;
virtual void initBokeh(int cornerAmount);
protected:
Bokeh bokehOptions;
inline Point2f biasSample(const CameraSample &sample) const {
if (bokehOptions.amount == 0)
return ConcentricSampleDisk(sample.pLens);
if (bokehOptions.amount == 4)
return sample.pLens;
if (bokehOptions.amount == -1) {
Point2f sampleOffset = 2.f * sample.pLens - Vector2f(1, 1);
if (sampleOffset.x == 0 || sampleOffset.y == 0) {
return Point2f(0, 0);
}
Float theta, r;
if (std::abs(sampleOffset.x) > std::abs(sampleOffset.y)) {
// r = std::pow(std::abs(sampleOffset.x),1/3.0f);
r = sampleOffset.x;
r = std::exp(-4 * r * r) - std::exp(-4);
r = sampleOffset.x < 0 ? -1 + r : 1 - r;
theta = PiOver4 * (sampleOffset.y / sampleOffset.x);
} else {
// r = std::pow(std::abs(sampleOffset.y),1/3.0f);
r = sampleOffset.y;
r = std::exp(-4 * r * r) - std::exp(-4);
r = sampleOffset.y < 0 ? -1 + r : 1 - r;
theta = PiOver2 - PiOver4 * (sampleOffset.x / sampleOffset.y);
}
return r * Point2f(std::cos(theta), std::sin(theta));
}
int index = int((sample.random - 0.000001f) * bokehOptions.amount);
int previous = index + 1 == bokehOptions.amount ? 0 : index + 1;
Point2f A = bokehOptions.corners[previous];
Point2f B = bokehOptions.corners[index];
Point2f C = Point2f(0, 0);
Float r1 = sample.pLens.x;
Float r2 = sample.pLens.y;
return (1 - sqrt(r1)) * A + (sqrt(r1) * (1 - r2)) * B + (sqrt(r1) * r2) * C;
}
};
inline std::ostream &operator<<(std::ostream &os, const CameraSample &cs) {
os << "[ pFilm: " << cs.pFilm << " , pLens: " << cs.pLens <<
StringPrintf(", time %f ]", cs.time);
return os;
}
protected:
// ProjectiveCamera Protected Data
Transform CameraToScreen, RasterToCamera;
Transform ScreenToRaster, RasterToScreen;
Float lensRadius, focalDistance;
};
class ProjectiveCamera : public Camera {
public:
// ProjectiveCamera Public Methods
ProjectiveCamera(const AnimatedTransform &CameraToWorld,
const Transform &CameraToScreen,
const Bounds2f &screenWindow, Float shutterOpen,
Float shutterClose, Float lensr, Float focald, Film *film,
const Medium *medium)
: Camera(CameraToWorld, shutterOpen, shutterClose, film, medium),
CameraToScreen(CameraToScreen) {
// Initialize depth of field parameters
lensRadius = lensr;
focalDistance = focald;
// Compute projective camera transformations
// Compute projective camera screen transformations
ScreenToRaster =
Scale(film->fullResolution.x, film->fullResolution.y, 1) *
Scale(1 / (screenWindow.pMax.x - screenWindow.pMin.x),
1 / (screenWindow.pMin.y - screenWindow.pMax.y), 1) *
Translate(Vector3f(-screenWindow.pMin.x, -screenWindow.pMax.y, 0));
RasterToScreen = Inverse(ScreenToRaster);
RasterToCamera = Inverse(CameraToScreen) * RasterToScreen;
}
protected:
// ProjectiveCamera Protected Data
Transform CameraToScreen, RasterToCamera;
Transform ScreenToRaster, RasterToScreen;
Float lensRadius, focalDistance;
};
} // namespace pbrt
......
......@@ -48,6 +48,7 @@ CameraSample Sampler::GetCameraSample(const Point2i &pRaster) {
cs.pFilm = (Point2f)pRaster + Get2D();
cs.time = Get1D();
cs.pLens = Get2D();
cs.random = Get1D();
return cs;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment