Commit 194896a8 authored by Jan Scheffczyk's avatar Jan Scheffczyk

changing to overlapping circles

parent 33862ea8
......@@ -47,9 +47,9 @@ 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, int bokehType)
PerspectiveCamera::PerspectiveCamera(const AnimatedTransform &CameraToWorld, const Bounds2f &screenWindow,
Float shutterOpen, Float shutterClose, Float lensRadius, Float focalDistance,
Float fov, Film *film, const Medium *medium, Bokeh bokehOpt)
: ProjectiveCamera(CameraToWorld, Perspective(fov, 1e-2f, 1000.f),
screenWindow, shutterOpen, shutterClose, lensRadius,
focalDistance, film, medium) {
......@@ -66,7 +66,8 @@ namespace pbrt {
pMin /= pMin.z;
pMax /= pMax.z;
A = std::abs((pMax.x - pMin.x) * (pMax.y - pMin.y));
initBokeh(bokehType);
bokehOptions= std::move(bokehOpt);
}
Float PerspectiveCamera::GenerateRay(const CameraSample &sample,
......@@ -285,13 +286,77 @@ PerspectiveCamera *CreatePerspectiveCamera(const ParamSet &params,
Float fov = params.FindOneFloat("fov", 90.);
Float halffov = params.FindOneFloat("halffov", -1.f);
Bokeh bokehOptions;
int edges = params.FindOneInt("lenselements", 0);
bokehOptions.blades=edges;
initBokehVerts(bokehOptions);
int amount;
const float *optical = params.FindFloat("optVign",&amount);
if(optical) {
if (amount != 3) {
Error("optVign expects 2 variables. I distribution of vignetting 1 for linear distribution, 2 for quadratic...), II parameter controls the strength of the vignetting");
}
std::cout << "found something"<<std::endl;
bokehOptions.optical_d=optical[1];
bokehOptions.optical_s=optical[0];
bokehOptions.optical_radius=optical[2];
}else{ // defaults (deactivates optical vignetting)
bokehOptions.optical_d=-1.0f;
bokehOptions.optical_s=-1.0f;
bokehOptions.optical_radius=1.5f;
}
const float *shape = params.FindFloat("shape",&amount);
if(shape) {
if (amount != 2) {
Error("optVign expects 3 variables. I distribution of vignetting 1 for linear distribution, 2 for quadratic...), II parameter controls the strength of the vignetting");
}
bokehOptions.shape_s=shape[0];
bokehOptions.shape_d=shape[1];
}else{ // defaults (deactivates optical vignetting)
bokehOptions.shape_s=0.6f;
bokehOptions.shape_d=0.2f;
}
const float *bias = params.FindFloat("bias",&amount);
if(bias) {
if (amount != 2) {
Error("2 parameters, I: bias distribution as exponent of a gaus function, if negative 1-gauß is used. II strength");
}
bokehOptions.bias_d= bias[1];
bokehOptions.bias_s= bias[0];
}else{ // default vals
bokehOptions.bias_d= 0;
bokehOptions.bias_s=1;
}
const float *edge = params.FindFloat("edge",&amount);
if(edge) {
if (amount != 2) {
Error("2 Parameters, I: [0-1]clamp, 0.9 => outer 0.1 make up the edge. II: how pronounced the edge is [0-1] ");
}
bokehOptions.edge_d= edge[1];
bokehOptions.edge_s= edge[0];
}else{
bokehOptions.edge_d= 1.0;
bokehOptions.edge_s= 0.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, edges);
medium, std::move(bokehOptions));
}
} // namespace pbrt
......@@ -49,9 +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, int bokehType);
PerspectiveCamera(const AnimatedTransform &CameraToWorld, const Bounds2f &screenWindow,
Float shutterOpen, Float shutterClose, Float lensRadius, Float focalDistance,
Float fov, Film *film, const Medium *medium, Bokeh bokehOpt);
Float GenerateRay(const CameraSample &sample, Ray *) const;
Float GenerateRayDifferential(const CameraSample &sample,
RayDifferential *ray) const;
......
......@@ -39,80 +39,77 @@
namespace pbrt {
// Camera Method Definitions
Camera::~Camera() { delete film; }
Camera::Camera(const AnimatedTransform &CameraToWorld, Float shutterOpen,
Float shutterClose, Film *film, const Medium *medium)
: CameraToWorld(CameraToWorld),
shutterOpen(shutterOpen),
shutterClose(shutterClose),
film(film),
medium(medium) {
if (CameraToWorld.HasScale())
Warning(
"Scaling detected in world-to-camera transformation!\n"
"The system has numerous assumptions, implicit and explicit,\n"
"that this transform will have no scale factors in it.\n"
"Proceed at your own risk; your image may have errors or\n"
"the system may crash as a result of this.");
}
Float Camera::GenerateRayDifferential(const CameraSample &sample,
RayDifferential *rd) const {
Float wt = GenerateRay(sample, rd);
// Find camera ray after shifting one pixel in the $x$ direction
CameraSample sshift = sample;
sshift.pFilm.x++;
Ray rx;
Float wtx = GenerateRay(sshift, &rx);
if (wtx == 0) return 0;
rd->rxOrigin = rx.o;
rd->rxDirection = rx.d;
// Find camera ray after shifting one pixel in the $y$ direction
sshift.pFilm.x--;
sshift.pFilm.y++;
Ray ry;
Float wty = GenerateRay(sshift, &ry);
if (wty == 0) return 0;
rd->ryOrigin = ry.o;
rd->ryDirection = ry.d;
rd->hasDifferentials = true;
return wt;
}
Spectrum Camera::We(const Ray &ray, Point2f *raster) const {
LOG(FATAL) << "Camera::We() is not implemented!";
return Spectrum(0.f);
}
void Camera::Pdf_We(const Ray &ray, Float *pdfPos, Float *pdfDir) const {
LOG(FATAL) << "Camera::Pdf_We() is not implemented!";
}
Spectrum Camera::Sample_Wi(const Interaction &ref, const Point2f &u,
Vector3f *wi, Float *pdf, Point2f *pRaster,
VisibilityTester *vis) const {
LOG(FATAL) << "Camera::Sample_Wi() is not implemented!";
return Spectrum(0.f);
}
void Camera::initBokeh(int cornerAmount) {
bokehOptions.amount=cornerAmount;
if(cornerAmount<=0)
return;
bokehOptions.step = 2 * Pi / cornerAmount;
bokehOptions.corners = std::unique_ptr<Point2f[]>(new Point2f[cornerAmount]);
float cur = Pi / 2.0f;
Camera::~Camera() { delete film; }
Camera::Camera(const AnimatedTransform &CameraToWorld, Float shutterOpen,
Float shutterClose, Film *film, const Medium *medium)
: CameraToWorld(CameraToWorld),
shutterOpen(shutterOpen),
shutterClose(shutterClose),
film(film),
medium(medium) {
if (CameraToWorld.HasScale())
Warning(
"Scaling detected in world-to-camera transformation!\n"
"The system has numerous assumptions, implicit and explicit,\n"
"that this transform will have no scale factors in it.\n"
"Proceed at your own risk; your image may have errors or\n"
"the system may crash as a result of this.");
}
Float Camera::GenerateRayDifferential(const CameraSample &sample,
RayDifferential *rd) const {
Float wt = GenerateRay(sample, rd);
// Find camera ray after shifting one pixel in the $x$ direction
CameraSample sshift = sample;
sshift.pFilm.x++;
Ray rx;
Float wtx = GenerateRay(sshift, &rx);
if (wtx == 0) return 0;
rd->rxOrigin = rx.o;
rd->rxDirection = rx.d;
// Find camera ray after shifting one pixel in the $y$ direction
sshift.pFilm.x--;
sshift.pFilm.y++;
Ray ry;
Float wty = GenerateRay(sshift, &ry);
if (wty == 0) return 0;
rd->ryOrigin = ry.o;
rd->ryDirection = ry.d;
rd->hasDifferentials = true;
return wt;
}
Spectrum Camera::We(const Ray &ray, Point2f *raster) const {
LOG(FATAL) << "Camera::We() is not implemented!";
return Spectrum(0.f);
}
Point2f* cornerArray= new Point2f[cornerAmount];
void Camera::Pdf_We(const Ray &ray, Float *pdfPos, Float *pdfDir) const {
LOG(FATAL) << "Camera::Pdf_We() is not implemented!";
}
Spectrum Camera::Sample_Wi(const Interaction &ref, const Point2f &u,
Vector3f *wi, Float *pdf, Point2f *pRaster,
VisibilityTester *vis) const {
LOG(FATAL) << "Camera::Sample_Wi() is not implemented!";
return Spectrum(0.f);
}
for (int i = 0; i < cornerAmount; i++) {
void initBokehVerts(Bokeh &bokehOptions) {
int nVert = bokehOptions.blades;
if (nVert <= 3)
return;
bokehOptions.step = 2 * Pi / nVert;
bokehOptions.corners = std::unique_ptr<Point2f[]>(new Point2f[nVert]);
float cur = Pi / 2.0f; // start at (0,1) with all polygons
for (int i = 0; i < nVert; i++) {
bokehOptions.corners[i] = Point2f(std::cos(cur), std::sin(cur));
cur += bokehOptions.step;
}
}
} // namespace pbrt
......@@ -56,11 +56,24 @@ namespace pbrt {
struct Bokeh {
// also used as type
int amount = 0;
int blades = 0;
// strength and distribution of optical vignetting
float optical_s = 1;
float optical_d = 1;
float shape_s = 0.5;
float shape_d = 2;
float bias_d = 0;
float bias_s = 1;
float edge_d = 1;
float edge_s = 0.6;
// caches to avoid recalc
float step;
std::unique_ptr<Point2f[]> corners;
float optical_radius;
};
void initBokehVerts(Bokeh &bokehOptions);
// Camera Declarations
class Camera {
public:
......@@ -89,8 +102,6 @@ namespace pbrt {
Film *film;
const Medium *medium;
virtual void initBokeh(int cornerAmount);
protected:
......@@ -98,118 +109,139 @@ namespace pbrt {
Bokeh bokehOptions;
inline Point2f biasSample(const CameraSample &sample, float &weight) const {
// return ConcentricSampleDisk(sample.pLens);
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);
Point2f ret = sample.pLens;
float quad = 0.0f;
if (sampleOffset.x == 0 || sampleOffset.y == 0) {
return Point2f(0, 0);
}
Float theta, r = 1.0;
if (std::abs(sampleOffset.x) > std::abs(sampleOffset.y)) {
// r = std::pow(std::abs(sampleOffset.x),1/3.0f);
r = sampleOffset.x;
if (bokehOptions.blades >= 3) {
theta = PiOver4 * (sampleOffset.y / sampleOffset.x);
} else {
Float a = sample.pLens.x;
// r = std::pow(std::abs(sampleOffset.y),1/3.0f);
r = sampleOffset.y;
float xSample = sample.pLens.x;
int index = static_cast<int>(xSample*bokehOptions.blades);
index= std::min(index,2);
theta = PiOver2 - PiOver4 * (sampleOffset.x / sampleOffset.y);
}
if (r <= -0.85)
r = -0.85;
if (r >= 0.85)
r = 0.85;
return r * Point2f(std::cos(theta), std::sin(theta));
xSample = (xSample-(index* (1.0f/bokehOptions.blades)))*bokehOptions.blades;
}
// int index = int((sample.random - 0.000001f) * bokehOptions.blades);
int previous = index + 1 == bokehOptions.blades ? 0 : index + 1;
Point2f A = bokehOptions.corners[previous];
Point2f B = bokehOptions.corners[index];
Point2f C = Point2f(0, 0);
if (bokehOptions.amount == -2) {
// Float r1 = sample.pLens.x;
Float r1 = xSample;
Float r2 = sample.pLens.y;
// edge and bias?
return Point2f(0, 0);
ret = (1 - sqrt(r1)) * A + (sqrt(r1) * (1 - r2)) * B + (sqrt(r1) * r2) * C;
quad = (1-r2);
}
if (bokehOptions.amount == -3) {
// optical vignetting enabled
else if (bokehOptions.optical_s > 0) {
Point2f sampleOffset = 2.f * sample.pLens - Vector2f(1, 1);
// convert film samples to [0-1] scale
Point2f ndc = sample.pFilm;
ndc.x /= film->fullResolution.x;
ndc.y /= film->fullResolution.y;
ndc.y = 1.0f-ndc.y;
ndc.y = 1.0f - ndc.y;
// convert to [-1,1]
ndc = 2.f * (ndc) - Vector2f(1, 1);
// quadric major axis angle
float alpha = -std::atan2(ndc.y,ndc.x)+Pi*0.5f;
float alpha = -std::atan2(ndc.y, ndc.x) + Pi * 0.5f;
float cos = std::cos(alpha);
float sin = std::sin(alpha);
//rotate sample
float xRot = cos * sampleOffset.x - sin*sampleOffset.y;
float xRot = cos * sampleOffset.x - sin * sampleOffset.y;
float yRot = sin * sampleOffset.x + cos * sampleOffset.y;
float str = bokehOptions.optical_s;
float dist = Vector2f(ndc).Length();
dist /= 1.8f;
float adist = dist;
// dist /= (str-1)*(str-1) +1.7f;
dist /= bokehOptions.optical_radius;
//distr
float distr = std::pow(0.1f + dist, bokehOptions.optical_d);
//shape
// dist = 1.0f- (std::exp(-4*dist*dist)-std::exp(-4));
float shape_s = bokehOptions.shape_s;
float shape_d = std::exp(-bokehOptions.shape_d * adist * adist);;
// float quad= (xRot*xRot+ std::max(1.0f,dist*3)*yRot*yRot);
//
float quad=0.0f;
if(yRot>=0){
quad= (xRot*xRot+ std::max(1.0f,(dist-0.1f)*4)*std::pow(yRot,(25.0f+15.0f*(1-dist))/20.0f));
float mult = 1 + str * 15;
float start = 40 * (1 - shape_s);
float end = 40 - start;
mult = 2.0f * std::pow(dist + 0.56f, 4) + 0.8;
// start=20.0f;
// end=20.0f;
if (yRot >= 0) {
quad = (xRot * xRot +
std::max(1.0f, (distr - 0.1f) * mult) * std::pow(yRot, (start + end * (shape_d)) / 20.0f));
} else {
quad = (xRot * xRot +
std::max(1.0f, (distr) * mult) *
std::pow(-yRot, ((start + 3) + (end - 3) * (shape_d)) / 20.0f));
}
else{
quad= (xRot*xRot+ std::max(1.0f,(dist)*4)*std::pow(-yRot,(20.0f+20.0f*(1-dist))/20.0f));
// rejection sampling
if (quad > 1) {
weight = 0.0f;
// bias
if(std::abs(bokehOptions.bias_d)>0.2f){
float b;
if(bokehOptions.bias_d<0){
float bias = -bokehOptions.bias_d;
b = std::exp(-bias*dist*dist);
b = 1-bokehOptions.bias_s*b;
}else{
b = bokehOptions.bias_s*std::exp(-bokehOptions.bias_d*dist*dist);
}
weight*=b;
}
if(quad>1){
weight=0.0f;
}
if(quad<0.9){
weight = 0.4f;
} else { //default circle
Point2f uOffset = 2.f * sample.pLens - Vector2f(1, 1);
// Handle degeneracy at the origin
if (uOffset.x == 0 && uOffset.y == 0) return Point2f(0, 0);
// Apply concentric mapping to point
Float theta, r;
if (std::abs(uOffset.x) > std::abs(uOffset.y)) {
r = uOffset.x;
theta = PiOver4 * (uOffset.y / uOffset.x);
} else {
r = uOffset.y;
theta = PiOver2 - PiOver4 * (uOffset.x / uOffset.y);
}
return sampleOffset;
ret = r * Point2f(std::cos(theta), std::sin(theta));
quad = std::abs(r);
}
if (bokehOptions.amount < 0) {
std::cerr << "not a valid option" << std::endl;
// edge
if (quad < bokehOptions.edge_d) {
weight = 1.0f - bokehOptions.edge_s;
}
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;
// default
return ret;
}
};
......@@ -253,7 +285,7 @@ namespace pbrt {
};
} // namespace pbrt
}
// namespace pbrt
#endif // PBRT_CORE_CAMERA_H
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