got it to compile
parent
ceaa1907c0
commit
df1a3fc3ba
|
@ -31,24 +31,27 @@ struct Ray {
|
||||||
Vector d; ///< Ray direction
|
Vector d; ///< Ray direction
|
||||||
Float maxt; ///< Maximum range for intersection tests
|
Float maxt; ///< Maximum range for intersection tests
|
||||||
Vector dRcp; ///< Componentwise reciprocals of the ray direction
|
Vector dRcp; ///< Componentwise reciprocals of the ray direction
|
||||||
|
Float time; ///< Time value associated with this ray
|
||||||
|
|
||||||
/// Construct a new ray
|
/// Construct a new ray
|
||||||
inline Ray() : mint(Epsilon), maxt(std::numeric_limits<Float>::infinity()) {
|
inline Ray() : mint(Epsilon),
|
||||||
|
maxt(std::numeric_limits<Float>::infinity()), time(0.0f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copy constructor (1)
|
/// Copy constructor (1)
|
||||||
inline Ray(const Ray &ray)
|
inline Ray(const Ray &ray)
|
||||||
: o(ray.o), mint(ray.mint), d(ray.d), maxt(ray.maxt), dRcp(ray.dRcp) {
|
: o(ray.o), mint(ray.mint), d(ray.d), maxt(ray.maxt),
|
||||||
|
dRcp(ray.dRcp), time(ray.time) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copy constructor (2)
|
/// Copy constructor (2)
|
||||||
inline Ray(const Ray &ray, Float mint, Float maxt)
|
inline Ray(const Ray &ray, Float mint, Float maxt)
|
||||||
: o(ray.o), mint(mint), d(ray.d), maxt(maxt), dRcp(ray.dRcp) {
|
: o(ray.o), mint(mint), d(ray.d), maxt(maxt), dRcp(ray.dRcp), time(ray.time) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new ray
|
/// Construct a new ray
|
||||||
inline Ray(Point o, Vector _d)
|
inline Ray(Point o, Vector _d, Float time)
|
||||||
: o(o), mint(Epsilon), d(_d), maxt(std::numeric_limits<Float>::infinity()) {
|
: o(o), mint(Epsilon), d(_d), maxt(std::numeric_limits<Float>::infinity()), time(time) {
|
||||||
#ifdef MTS_DEBUG_FP
|
#ifdef MTS_DEBUG_FP
|
||||||
disable_fpexcept();
|
disable_fpexcept();
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,8 +64,8 @@ struct Ray {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new ray
|
/// Construct a new ray
|
||||||
inline Ray(Point o, Vector _d, Float mint, Float maxt)
|
inline Ray(Point o, Vector _d, Float mint, Float maxt, Float time)
|
||||||
: o(o), mint(mint), d(_d), maxt(maxt) {
|
: o(o), mint(mint), d(_d), maxt(maxt), time(time) {
|
||||||
#ifdef MTS_DEBUG_FP
|
#ifdef MTS_DEBUG_FP
|
||||||
disable_fpexcept();
|
disable_fpexcept();
|
||||||
#endif
|
#endif
|
||||||
|
@ -77,6 +80,9 @@ struct Ray {
|
||||||
/// Set the origin
|
/// Set the origin
|
||||||
inline void setOrigin(const Point &oVal) { o = oVal; }
|
inline void setOrigin(const Point &oVal) { o = oVal; }
|
||||||
|
|
||||||
|
/// Set the origin
|
||||||
|
inline void setTime(const Float &tval) { time = tval; }
|
||||||
|
|
||||||
/// Set the direction and update the reciprocal
|
/// Set the direction and update the reciprocal
|
||||||
inline void setDirection(const Vector &dVal) {
|
inline void setDirection(const Vector &dVal) {
|
||||||
d = dVal;
|
d = dVal;
|
||||||
|
@ -97,7 +103,8 @@ struct Ray {
|
||||||
/// Return a string representation of this ray
|
/// Return a string representation of this ray
|
||||||
inline std::string toString() const {
|
inline std::string toString() const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Ray[orig=" << o.toString() << ", dest=" << d.toString() << "]";
|
oss << "Ray[orig=" << o.toString() << ", dest="
|
||||||
|
<< d.toString() << ", time=" << time << "]";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -112,8 +119,8 @@ struct RayDifferential : public Ray {
|
||||||
: hasDifferentials(false) {
|
: hasDifferentials(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline RayDifferential(const Point &p, const Vector &d)
|
inline RayDifferential(const Point &p, const Vector &d, Float time)
|
||||||
: Ray(p, d), hasDifferentials(false) {
|
: Ray(p, d, time), hasDifferentials(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline explicit RayDifferential(const Ray &ray)
|
inline explicit RayDifferential(const Ray &ray)
|
||||||
|
|
|
@ -310,6 +310,7 @@ public:
|
||||||
b.dRcp.x = 1.0f / b.d.x;
|
b.dRcp.x = 1.0f / b.d.x;
|
||||||
b.dRcp.y = 1.0f / b.d.y;
|
b.dRcp.y = 1.0f / b.d.y;
|
||||||
b.dRcp.z = 1.0f / b.d.z;
|
b.dRcp.z = 1.0f / b.d.z;
|
||||||
|
b.time = a.time;
|
||||||
#ifdef MTS_DEBUG_FP
|
#ifdef MTS_DEBUG_FP
|
||||||
enable_fpexcept();
|
enable_fpexcept();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,11 +31,11 @@ class MTS_EXPORT_RENDER Camera : public ConfigurableObject {
|
||||||
public:
|
public:
|
||||||
/// Create a ray from the given sample
|
/// Create a ray from the given sample
|
||||||
virtual void generateRay(const Point2 &sample, const Point2 &lensSample,
|
virtual void generateRay(const Point2 &sample, const Point2 &lensSample,
|
||||||
Ray &ray) const = 0;
|
Float timeSample, Ray &ray) const = 0;
|
||||||
|
|
||||||
/// Create ray differentials from the given sample
|
/// Create ray differentials from the given sample
|
||||||
void generateRayDifferential(const Point2 &sample,
|
void generateRayDifferential(const Point2 &sample,
|
||||||
const Point2 &lensSample, RayDifferential &ray) const;
|
const Point2 &lensSample, Float timeSample, RayDifferential &ray) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn a world-space position into fractional pixel coordinates.
|
* Turn a world-space position into fractional pixel coordinates.
|
||||||
|
@ -47,6 +47,9 @@ public:
|
||||||
/// Does generateRay() expect a proper lens sample?
|
/// Does generateRay() expect a proper lens sample?
|
||||||
virtual bool needsLensSample() const = 0;
|
virtual bool needsLensSample() const = 0;
|
||||||
|
|
||||||
|
/// Does generateRay() expect a proper time sample?
|
||||||
|
inline bool needsTimeSample() const { return m_shutterOpenTime > 0; }
|
||||||
|
|
||||||
/// Return the camera position (approximate in the case of finite sensor area)
|
/// Return the camera position (approximate in the case of finite sensor area)
|
||||||
inline const Point &getPosition() const { return m_position; }
|
inline const Point &getPosition() const { return m_position; }
|
||||||
|
|
||||||
|
@ -81,6 +84,15 @@ public:
|
||||||
*/
|
*/
|
||||||
inline const Sampler *getSampler() const { return m_sampler.get(); }
|
inline const Sampler *getSampler() const { return m_sampler.get(); }
|
||||||
|
|
||||||
|
/// Return the time value of the shutter opening event
|
||||||
|
inline Float getShutterOpen() const { return m_shutterOpen; }
|
||||||
|
|
||||||
|
/// Return the length, for which the shutter remains open
|
||||||
|
inline Float getShutterOpenTime() const { return m_shutterOpenTime; }
|
||||||
|
|
||||||
|
/// Return the time value of the shutter closing event
|
||||||
|
inline Float getShutterClose() const { return m_shutterOpen; }
|
||||||
|
|
||||||
/// Return the image plane normal
|
/// Return the image plane normal
|
||||||
inline Normal getImagePlaneNormal() const {
|
inline Normal getImagePlaneNormal() const {
|
||||||
return Normal(normalize(m_cameraToWorld(Vector(0, 0, 1))));
|
return Normal(normalize(m_cameraToWorld(Vector(0, 0, 1))));
|
||||||
|
@ -143,6 +155,7 @@ protected:
|
||||||
Transform m_worldToCamera, m_cameraToWorld;
|
Transform m_worldToCamera, m_cameraToWorld;
|
||||||
Point m_position;
|
Point m_position;
|
||||||
Properties m_properties;
|
Properties m_properties;
|
||||||
|
Float m_shutterOpen, m_shutterClose, m_shutterOpenTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTS_EXPORT_RENDER ProjectiveCamera : public Camera {
|
class MTS_EXPORT_RENDER ProjectiveCamera : public Camera {
|
||||||
|
|
|
@ -3163,7 +3163,7 @@ template <typename AABBType, typename Derived>
|
||||||
sample2(random->nextFloat(), random->nextFloat());
|
sample2(random->nextFloat(), random->nextFloat());
|
||||||
Point p1 = bsphere.center + squareToSphere(sample1) * bsphere.radius;
|
Point p1 = bsphere.center + squareToSphere(sample1) * bsphere.radius;
|
||||||
Point p2 = bsphere.center + squareToSphere(sample2) * bsphere.radius;
|
Point p2 = bsphere.center + squareToSphere(sample2) * bsphere.radius;
|
||||||
Ray ray(p1, normalize(p2-p1));
|
Ray ray(p1, normalize(p2-p1), 0.0f);
|
||||||
Float mint, maxt, t;
|
Float mint, maxt, t;
|
||||||
if (this->m_aabb.rayIntersect(ray, mint, maxt)) {
|
if (this->m_aabb.rayIntersect(ray, mint, maxt)) {
|
||||||
if (ray.mint > mint) mint = ray.mint;
|
if (ray.mint > mint) mint = ray.mint;
|
||||||
|
|
|
@ -288,7 +288,7 @@ public:
|
||||||
* cosine-weighted sampling and a configurable number of rays.
|
* cosine-weighted sampling and a configurable number of rays.
|
||||||
*/
|
*/
|
||||||
virtual Spectrum E(const Scene *scene, const Point &p, const
|
virtual Spectrum E(const Scene *scene, const Point &p, const
|
||||||
Normal &n, Sampler *sampler) const;
|
Normal &n, Float time, Sampler *sampler) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform the main rendering task. The work is automatically
|
* Perform the main rendering task. The work is automatically
|
||||||
|
|
|
@ -353,6 +353,7 @@ protected:
|
||||||
shape->fillIntersectionRecord(ray,
|
shape->fillIntersectionRecord(ray,
|
||||||
reinterpret_cast<const uint8_t*>(temp) + 8, its);
|
reinterpret_cast<const uint8_t*>(temp) + 8, its);
|
||||||
}
|
}
|
||||||
|
its.time = ray.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Plain shadow ray query (used by the 'instance' plugin)
|
/// Plain shadow ray query (used by the 'instance' plugin)
|
||||||
|
|
|
@ -106,7 +106,7 @@ public:
|
||||||
* which occurred while tracing particles.
|
* which occurred while tracing particles.
|
||||||
*/
|
*/
|
||||||
virtual void handleMediumInteraction(int depth, bool caustic,
|
virtual void handleMediumInteraction(int depth, bool caustic,
|
||||||
const MediumSamplingRecord &mRec, const Vector &wi,
|
const MediumSamplingRecord &mRec, Float time, const Vector &wi,
|
||||||
const Spectrum &weight);
|
const Spectrum &weight);
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
|
|
|
@ -64,7 +64,7 @@ inline bool RadianceQueryRecord::rayIntersect(const RayDifferential &ray) {
|
||||||
/* Only search for an intersection if this was explicitly requested */
|
/* Only search for an intersection if this was explicitly requested */
|
||||||
if (type & EIntersection) {
|
if (type & EIntersection) {
|
||||||
scene->rayIntersect(ray, its);
|
scene->rayIntersect(ray, its);
|
||||||
attenuation = scene->getAttenuation(Ray(ray.o, ray.d, 0, its.t));
|
attenuation = scene->getAttenuation(Ray(ray.o, ray.d, 0, its.t, ray.time));
|
||||||
if (type & EOpacity)
|
if (type & EOpacity)
|
||||||
alpha = its.isValid() ? 1 : (1 - attenuation.average());
|
alpha = its.isValid() ? 1 : (1 - attenuation.average());
|
||||||
if (type & EDistance)
|
if (type & EDistance)
|
||||||
|
|
|
@ -131,8 +131,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cast a shadow ray
|
/// Cast a shadow ray
|
||||||
inline bool isOccluded(const Point &p1, const Point &p2) const {
|
inline bool isOccluded(const Point &p1, const Point &p2, Float time) const {
|
||||||
Ray ray(p1, p2-p1);
|
Ray ray(p1, p2-p1, time);
|
||||||
ray.mint = ShadowEpsilon;
|
ray.mint = ShadowEpsilon;
|
||||||
ray.maxt = 1-ShadowEpsilon;
|
ray.maxt = 1-ShadowEpsilon;
|
||||||
return m_kdtree->rayIntersect(ray);
|
return m_kdtree->rayIntersect(ray);
|
||||||
|
@ -155,6 +155,9 @@ public:
|
||||||
* @param lRec
|
* @param lRec
|
||||||
* A luminaire sampling record, which will hold information such as the
|
* A luminaire sampling record, which will hold information such as the
|
||||||
* probability density, associated measure etc.
|
* probability density, associated measure etc.
|
||||||
|
* @param time
|
||||||
|
* Associated time value -- this is needed to check the visibility when
|
||||||
|
* objects are potentially moving over time
|
||||||
* @param testVisibility
|
* @param testVisibility
|
||||||
* If this is true, a shadow-ray will be cast to ensure that no surface
|
* If this is true, a shadow-ray will be cast to ensure that no surface
|
||||||
* blocks the path lRec.sRec.p <-> p.
|
* blocks the path lRec.sRec.p <-> p.
|
||||||
|
@ -162,7 +165,8 @@ public:
|
||||||
* true if sampling was successful
|
* true if sampling was successful
|
||||||
*/
|
*/
|
||||||
bool sampleLuminaire(const Point &p,
|
bool sampleLuminaire(const Point &p,
|
||||||
LuminaireSamplingRecord &lRec, const Point2 &sample, bool testVisibility = true) const;
|
LuminaireSamplingRecord &lRec, Float time,
|
||||||
|
const Point2 &sample, bool testVisibility = true) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample a visible point on a luminaire (ideally uniform wrt. the solid angle of p). Takes
|
* Sample a visible point on a luminaire (ideally uniform wrt. the solid angle of p). Takes
|
||||||
|
@ -186,9 +190,10 @@ public:
|
||||||
* lRec.Le by the integrated extinction coefficient on the path lRec.sRec.p <-> p.
|
* lRec.Le by the integrated extinction coefficient on the path lRec.sRec.p <-> p.
|
||||||
*/
|
*/
|
||||||
inline bool sampleLuminaireAttenuated(const Point &p,
|
inline bool sampleLuminaireAttenuated(const Point &p,
|
||||||
LuminaireSamplingRecord &lRec, const Point2 &sample, bool testVisibility = true) const {
|
LuminaireSamplingRecord &lRec, Float time,
|
||||||
if (sampleLuminaire(p, lRec, sample, testVisibility)) {
|
const Point2 &sample, bool testVisibility = true) const {
|
||||||
lRec.Le *= getAttenuation(Ray(p, lRec.sRec.p-p, 0, 1));
|
if (sampleLuminaire(p, lRec, time, sample, testVisibility)) {
|
||||||
|
lRec.Le *= getAttenuation(Ray(p, lRec.sRec.p-p, 0, 1, 0));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -201,7 +206,7 @@ public:
|
||||||
inline bool sampleLuminaireAttenuated(const Intersection &its,
|
inline bool sampleLuminaireAttenuated(const Intersection &its,
|
||||||
LuminaireSamplingRecord &lRec, const Point2 &sample, bool testVisibility = true) const {
|
LuminaireSamplingRecord &lRec, const Point2 &sample, bool testVisibility = true) const {
|
||||||
if (sampleLuminaire(its, lRec, sample, testVisibility)) {
|
if (sampleLuminaire(its, lRec, sample, testVisibility)) {
|
||||||
lRec.Le *= getAttenuation(Ray(its.p, lRec.sRec.p-its.p, 0, 1));
|
lRec.Le *= getAttenuation(Ray(its.p, lRec.sRec.p-its.p, 0, 1, 0));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -132,6 +132,9 @@ public:
|
||||||
/// Texture coordinate mapping partials wrt. changes in screen-space
|
/// Texture coordinate mapping partials wrt. changes in screen-space
|
||||||
Float dudx, dudy, dvdx, dvdy;
|
Float dudx, dudy, dvdx, dvdy;
|
||||||
|
|
||||||
|
/// Time value associated with the intersection
|
||||||
|
Float time;
|
||||||
|
|
||||||
/// Interpolated vertex color
|
/// Interpolated vertex color
|
||||||
Spectrum color;
|
Spectrum color;
|
||||||
|
|
||||||
|
|
|
@ -104,13 +104,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateRay(const Point2 &dirSample, const Point2 &lensSample,
|
void generateRay(const Point2 &dirSample, const Point2 &lensSample,
|
||||||
Ray &ray) const {
|
Float timeSample, Ray &ray) const {
|
||||||
Point rasterCoords(dirSample.x, dirSample.y, 0);
|
Point rasterCoords(dirSample.x, dirSample.y, 0);
|
||||||
Point imageCoords;
|
Point imageCoords;
|
||||||
m_rasterToCamera(rasterCoords, imageCoords);
|
m_rasterToCamera(rasterCoords, imageCoords);
|
||||||
|
|
||||||
/* Construct ray in camera space */
|
/* Construct ray in camera space */
|
||||||
Ray localRay(imageCoords, Vector(0, 0, 1));
|
Ray localRay(imageCoords, Vector(0, 0, 1),
|
||||||
|
m_shutterOpen + m_shutterOpenTime * timeSample);
|
||||||
localRay.mint = 0;
|
localRay.mint = 0;
|
||||||
localRay.maxt = m_farClip - m_nearClip;
|
localRay.maxt = m_farClip - m_nearClip;
|
||||||
|
|
||||||
|
@ -154,6 +155,8 @@ public:
|
||||||
<< " aspect = " << m_aspect << "," << std::endl
|
<< " aspect = " << m_aspect << "," << std::endl
|
||||||
<< " nearClip = " << m_nearClip << "," << std::endl
|
<< " nearClip = " << m_nearClip << "," << std::endl
|
||||||
<< " farClip = " << m_farClip << "," << std::endl
|
<< " farClip = " << m_farClip << "," << std::endl
|
||||||
|
<< " shutterOpen = " << m_shutterOpen << "," << std::endl
|
||||||
|
<< " shutterClose = " << m_shutterClose << "," << std::endl
|
||||||
<< " areaDensity = " << m_areaDensity << "," << std::endl
|
<< " areaDensity = " << m_areaDensity << "," << std::endl
|
||||||
<< " cameraToWorld = " << indent(m_cameraToWorld.toString()) << "," << std::endl
|
<< " cameraToWorld = " << indent(m_cameraToWorld.toString()) << "," << std::endl
|
||||||
<< " cameraToScreen = " << indent(m_cameraToScreen.toString()) << "," << std::endl
|
<< " cameraToScreen = " << indent(m_cameraToScreen.toString()) << "," << std::endl
|
||||||
|
|
|
@ -110,14 +110,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateRay(const Point2 &dirSample, const Point2 &lensSample,
|
void generateRay(const Point2 &dirSample, const Point2 &lensSample,
|
||||||
Ray &ray) const {
|
Float timeSample, Ray &ray) const {
|
||||||
/* Calculate intersection on the image plane */
|
/* Calculate intersection on the image plane */
|
||||||
Point rasterCoords(dirSample.x, dirSample.y, 0);
|
Point rasterCoords(dirSample.x, dirSample.y, 0);
|
||||||
Point imageCoords;
|
Point imageCoords;
|
||||||
m_rasterToCamera(rasterCoords, imageCoords);
|
m_rasterToCamera(rasterCoords, imageCoords);
|
||||||
|
|
||||||
/* Construct ray in camera space */
|
/* Construct ray in camera space */
|
||||||
Ray localRay(Point(0, 0, 0), Vector(imageCoords));
|
Ray localRay(Point(0, 0, 0), Vector(imageCoords),
|
||||||
|
m_shutterOpen + m_shutterOpenTime * timeSample);
|
||||||
|
|
||||||
if (m_lensRadius > 0.0f) {
|
if (m_lensRadius > 0.0f) {
|
||||||
/* Sample a point on the aperture */
|
/* Sample a point on the aperture */
|
||||||
|
@ -184,6 +185,8 @@ public:
|
||||||
<< " yfov = " << m_yfov << "," << std::endl
|
<< " yfov = " << m_yfov << "," << std::endl
|
||||||
<< " nearClip = " << m_nearClip << "," << std::endl
|
<< " nearClip = " << m_nearClip << "," << std::endl
|
||||||
<< " farClip = " << m_farClip << "," << std::endl
|
<< " farClip = " << m_farClip << "," << std::endl
|
||||||
|
<< " shutterOpen = " << m_shutterOpen << "," << std::endl
|
||||||
|
<< " shutterClose = " << m_shutterClose << "," << std::endl
|
||||||
<< " lensRadius = " << m_lensRadius << "," << std::endl
|
<< " lensRadius = " << m_lensRadius << "," << std::endl
|
||||||
<< " focalDistance = " << m_focalDistance << "," << std::endl
|
<< " focalDistance = " << m_focalDistance << "," << std::endl
|
||||||
<< " cameraToWorld = " << indent(m_cameraToWorld.toString()) << "," << std::endl
|
<< " cameraToWorld = " << indent(m_cameraToWorld.toString()) << "," << std::endl
|
||||||
|
|
|
@ -168,7 +168,7 @@ public:
|
||||||
bsdfVal /= bsdfPdf;
|
bsdfVal /= bsdfPdf;
|
||||||
|
|
||||||
/* Trace a ray in this direction */
|
/* Trace a ray in this direction */
|
||||||
Ray bsdfRay(its.p, its.toWorld(bRec.wo));
|
Ray bsdfRay(its.p, its.toWorld(bRec.wo), ray.time);
|
||||||
bool hitLuminaire = false;
|
bool hitLuminaire = false;
|
||||||
if (scene->rayIntersect(bsdfRay, bsdfIts)) {
|
if (scene->rayIntersect(bsdfRay, bsdfIts)) {
|
||||||
bsdfRay.mint = 0; bsdfRay.maxt = bsdfIts.t;
|
bsdfRay.mint = 0; bsdfRay.maxt = bsdfIts.t;
|
||||||
|
|
|
@ -103,8 +103,9 @@ public:
|
||||||
|
|
||||||
Vector2i filmSize = camera->getFilm()->getSize();
|
Vector2i filmSize = camera->getFilm()->getSize();
|
||||||
bool needsLensSample = camera->needsLensSample();
|
bool needsLensSample = camera->needsLensSample();
|
||||||
|
bool needsTimeSample = camera->needsTimeSample();
|
||||||
const int nSamples = 10000;
|
const int nSamples = 10000;
|
||||||
Float luminance = 0;
|
Float luminance = 0, timeSample = 0;
|
||||||
RadianceQueryRecord rRec(scene, sampler);
|
RadianceQueryRecord rRec(scene, sampler);
|
||||||
for (int i=0; i<nSamples; ++i) {
|
for (int i=0; i<nSamples; ++i) {
|
||||||
Point2 sample, lensSample;
|
Point2 sample, lensSample;
|
||||||
|
@ -113,10 +114,12 @@ public:
|
||||||
rRec.newQuery(RadianceQueryRecord::ERadiance);
|
rRec.newQuery(RadianceQueryRecord::ERadiance);
|
||||||
if (needsLensSample)
|
if (needsLensSample)
|
||||||
lensSample = rRec.nextSample2D();
|
lensSample = rRec.nextSample2D();
|
||||||
|
if (needsTimeSample)
|
||||||
|
timeSample = rRec.nextSample1D();
|
||||||
sample = rRec.nextSample2D();
|
sample = rRec.nextSample2D();
|
||||||
sample.x *= filmSize.x;
|
sample.x *= filmSize.x;
|
||||||
sample.y *= filmSize.y;
|
sample.y *= filmSize.y;
|
||||||
camera->generateRayDifferential(sample, lensSample, eyeRay);
|
camera->generateRayDifferential(sample, lensSample, timeSample, eyeRay);
|
||||||
|
|
||||||
luminance += m_subIntegrator->Li(eyeRay, rRec).getLuminance();
|
luminance += m_subIntegrator->Li(eyeRay, rRec).getLuminance();
|
||||||
}
|
}
|
||||||
|
@ -130,13 +133,14 @@ public:
|
||||||
void renderBlock(const Scene *scene, const Camera *camera, Sampler *sampler,
|
void renderBlock(const Scene *scene, const Camera *camera, Sampler *sampler,
|
||||||
ImageBlock *block, const bool &stop) const {
|
ImageBlock *block, const bool &stop) const {
|
||||||
bool needsLensSample = camera->needsLensSample();
|
bool needsLensSample = camera->needsLensSample();
|
||||||
|
bool needsTimeSample = camera->needsTimeSample();
|
||||||
const TabulatedFilter *filter = camera->getFilm()->getTabulatedFilter();
|
const TabulatedFilter *filter = camera->getFilm()->getTabulatedFilter();
|
||||||
|
|
||||||
Float mean, meanSqr;
|
Float mean, meanSqr;
|
||||||
Point2 sample, lensSample;
|
Point2 sample, lensSample;
|
||||||
RayDifferential eyeRay;
|
RayDifferential eyeRay;
|
||||||
int x, y;
|
int x, y;
|
||||||
Float sampleLuminance;
|
Float sampleLuminance, timeSample = 0;
|
||||||
RadianceQueryRecord rRec(scene, sampler);
|
RadianceQueryRecord rRec(scene, sampler);
|
||||||
int sampleIndex;
|
int sampleIndex;
|
||||||
|
|
||||||
|
@ -157,10 +161,12 @@ public:
|
||||||
rRec.newQuery(RadianceQueryRecord::ECameraRay);
|
rRec.newQuery(RadianceQueryRecord::ECameraRay);
|
||||||
if (needsLensSample)
|
if (needsLensSample)
|
||||||
lensSample = rRec.nextSample2D();
|
lensSample = rRec.nextSample2D();
|
||||||
|
if (needsTimeSample)
|
||||||
|
timeSample = rRec.nextSample1D();
|
||||||
sample = rRec.nextSample2D();
|
sample = rRec.nextSample2D();
|
||||||
sample.x += x; sample.y += y;
|
sample.x += x; sample.y += y;
|
||||||
camera->generateRayDifferential(sample,
|
camera->generateRayDifferential(sample,
|
||||||
lensSample, eyeRay);
|
lensSample, timeSample, eyeRay);
|
||||||
|
|
||||||
Spectrum sampleValue = m_subIntegrator->Li(eyeRay, rRec);
|
Spectrum sampleValue = m_subIntegrator->Li(eyeRay, rRec);
|
||||||
|
|
||||||
|
@ -217,8 +223,8 @@ public:
|
||||||
return m_subIntegrator->Li(ray, rRec);
|
return m_subIntegrator->Li(ray, rRec);
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum E(const Scene *scene, const Point &p, const Normal &n, Sampler *sampler) const {
|
Spectrum E(const Scene *scene, const Point &p, const Normal &n, Float time, Sampler *sampler) const {
|
||||||
return m_subIntegrator->E(scene, p, n, sampler);
|
return m_subIntegrator->E(scene, p, n, time, sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(Stream *stream, InstanceManager *manager) const {
|
void serialize(Stream *stream, InstanceManager *manager) const {
|
||||||
|
|
|
@ -277,7 +277,7 @@ public:
|
||||||
RadianceQueryRecord::ERadianceNoEmission | RadianceQueryRecord::EDistance);
|
RadianceQueryRecord::ERadianceNoEmission | RadianceQueryRecord::EDistance);
|
||||||
rRec2.extra = 1;
|
rRec2.extra = 1;
|
||||||
rRec2.sampler = sampler;
|
rRec2.sampler = sampler;
|
||||||
entry.L = m_subIntegrator->Li(RayDifferential(rRec.its.p, entry.d), rRec2);
|
entry.L = m_subIntegrator->Li(RayDifferential(rRec.its.p, entry.d, ray.time), rRec2);
|
||||||
entry.dist = rRec2.dist;
|
entry.dist = rRec2.dist;
|
||||||
sampler->advance();
|
sampler->advance();
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ public:
|
||||||
E = hs->getIrradiance();
|
E = hs->getIrradiance();
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum E(const Scene *scene, const Point &p, const Normal &n, Sampler *sampler) const {
|
Spectrum E(const Scene *scene, const Point &p, const Normal &n, Float time, Sampler *sampler) const {
|
||||||
Spectrum EDir(0.0f), EIndir(0.0f);
|
Spectrum EDir(0.0f), EIndir(0.0f);
|
||||||
RadianceQueryRecord rRec(scene, sampler);
|
RadianceQueryRecord rRec(scene, sampler);
|
||||||
LuminaireSamplingRecord lRec;
|
LuminaireSamplingRecord lRec;
|
||||||
|
@ -297,7 +297,7 @@ public:
|
||||||
for (unsigned int i=0; i<m_irrSamples; i++) {
|
for (unsigned int i=0; i<m_irrSamples; i++) {
|
||||||
rRec.newQuery(RadianceQueryRecord::ERadianceNoEmission);
|
rRec.newQuery(RadianceQueryRecord::ERadianceNoEmission);
|
||||||
|
|
||||||
if (scene->sampleLuminaireAttenuated(p, lRec, rRec.nextSample2D())) {
|
if (scene->sampleLuminaireAttenuated(p, lRec, time, rRec.nextSample2D())) {
|
||||||
Float dp = dot(lRec.d, n);
|
Float dp = dot(lRec.d, n);
|
||||||
if (dp < 0)
|
if (dp < 0)
|
||||||
EDir -= lRec.Le * dp;
|
EDir -= lRec.Le * dp;
|
||||||
|
|
|
@ -104,7 +104,7 @@ public:
|
||||||
if (stop)
|
if (stop)
|
||||||
break;
|
break;
|
||||||
Point2 sample(x + .5f, y + .5f);
|
Point2 sample(x + .5f, y + .5f);
|
||||||
m_camera->generateRayDifferential(sample, lensSample, eyeRay);
|
m_camera->generateRayDifferential(sample, lensSample, 0.0f, eyeRay);
|
||||||
if (m_scene->rayIntersect(eyeRay, its)) {
|
if (m_scene->rayIntersect(eyeRay, its)) {
|
||||||
const BSDF *bsdf = its.shape->getBSDF();
|
const BSDF *bsdf = its.shape->getBSDF();
|
||||||
if (!bsdf->getType() == BSDF::EDiffuseReflection)
|
if (!bsdf->getType() == BSDF::EDiffuseReflection)
|
||||||
|
@ -125,7 +125,7 @@ public:
|
||||||
rRec.newQuery(RadianceQueryRecord::ERadianceNoEmission | RadianceQueryRecord::EDistance);
|
rRec.newQuery(RadianceQueryRecord::ERadianceNoEmission | RadianceQueryRecord::EDistance);
|
||||||
rRec.depth = 2;
|
rRec.depth = 2;
|
||||||
rRec.extra = 1; // mark as irradiance cache query
|
rRec.extra = 1; // mark as irradiance cache query
|
||||||
entry.L = integrator->Li(RayDifferential(its.p, entry.d), rRec);
|
entry.L = integrator->Li(RayDifferential(its.p, entry.d, 0.0f), rRec);
|
||||||
entry.dist = rRec.dist;
|
entry.dist = rRec.dist;
|
||||||
m_sampler->advance();
|
m_sampler->advance();
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ public:
|
||||||
prevIts = its;
|
prevIts = its;
|
||||||
|
|
||||||
/* Trace a ray in this direction */
|
/* Trace a ray in this direction */
|
||||||
ray = Ray(its.p, its.toWorld(bRec.wo));
|
ray = Ray(its.p, its.toWorld(bRec.wo), ray.time);
|
||||||
bool hitLuminaire = false;
|
bool hitLuminaire = false;
|
||||||
if (scene->rayIntersect(ray, its)) {
|
if (scene->rayIntersect(ray, its)) {
|
||||||
/* Intersected something - check if it was a luminaire */
|
/* Intersected something - check if it was a luminaire */
|
||||||
|
|
|
@ -77,7 +77,7 @@ void CaptureParticleWorker::handleSurfaceInteraction(int, bool,
|
||||||
|
|
||||||
if (m_camera->positionToSample(its.p, screenSample)) {
|
if (m_camera->positionToSample(its.p, screenSample)) {
|
||||||
Point cameraPosition = m_camera->getPosition(screenSample);
|
Point cameraPosition = m_camera->getPosition(screenSample);
|
||||||
if (m_scene->isOccluded(cameraPosition, its.p))
|
if (m_scene->isOccluded(cameraPosition, its.p, its.time))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const BSDF *bsdf = its.shape->getBSDF();
|
const BSDF *bsdf = its.shape->getBSDF();
|
||||||
|
@ -94,7 +94,7 @@ void CaptureParticleWorker::handleSurfaceInteraction(int, bool,
|
||||||
importance = 1/m_camera->areaDensity(screenSample);
|
importance = 1/m_camera->areaDensity(screenSample);
|
||||||
|
|
||||||
/* Compute Le * importance and store it in an accumulation buffer */
|
/* Compute Le * importance and store it in an accumulation buffer */
|
||||||
Ray ray(its.p, d, 0, dist);
|
Ray ray(its.p, d, 0, dist, its.time);
|
||||||
Spectrum sampleVal = weight * bsdf->fCos(bRec)
|
Spectrum sampleVal = weight * bsdf->fCos(bRec)
|
||||||
* m_scene->getAttenuation(ray) * importance;
|
* m_scene->getAttenuation(ray) * importance;
|
||||||
|
|
||||||
|
@ -103,13 +103,13 @@ void CaptureParticleWorker::handleSurfaceInteraction(int, bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureParticleWorker::handleMediumInteraction(int, bool,
|
void CaptureParticleWorker::handleMediumInteraction(int, bool,
|
||||||
const MediumSamplingRecord &mRec, const Vector &wi,
|
const MediumSamplingRecord &mRec, Float time, const Vector &wi,
|
||||||
const Spectrum &weight) {
|
const Spectrum &weight) {
|
||||||
Point2 screenSample;
|
Point2 screenSample;
|
||||||
|
|
||||||
if (m_camera->positionToSample(mRec.p, screenSample)) {
|
if (m_camera->positionToSample(mRec.p, screenSample)) {
|
||||||
Point cameraPosition = m_camera->getPosition(screenSample);
|
Point cameraPosition = m_camera->getPosition(screenSample);
|
||||||
if (m_scene->isOccluded(cameraPosition, mRec.p))
|
if (m_scene->isOccluded(cameraPosition, mRec.p, time))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Vector wo = cameraPosition - mRec.p;
|
Vector wo = cameraPosition - mRec.p;
|
||||||
|
@ -122,7 +122,7 @@ void CaptureParticleWorker::handleMediumInteraction(int, bool,
|
||||||
importance = 1/m_camera->areaDensity(screenSample);
|
importance = 1/m_camera->areaDensity(screenSample);
|
||||||
|
|
||||||
/* Compute Le * importance and store in accumulation buffer */
|
/* Compute Le * importance and store in accumulation buffer */
|
||||||
Ray ray(mRec.p, wo, 0, dist);
|
Ray ray(mRec.p, wo, 0, dist, time);
|
||||||
|
|
||||||
Spectrum sampleVal = weight * mRec.medium->getPhaseFunction()->f(mRec, wi, wo)
|
Spectrum sampleVal = weight * mRec.medium->getPhaseFunction()->f(mRec, wi, wo)
|
||||||
* m_scene->getAttenuation(ray) * importance;
|
* m_scene->getAttenuation(ray) * importance;
|
||||||
|
|
|
@ -103,7 +103,7 @@ public:
|
||||||
* pixel of the accumulation buffer.
|
* pixel of the accumulation buffer.
|
||||||
*/
|
*/
|
||||||
void handleMediumInteraction(int depth, bool caustic,
|
void handleMediumInteraction(int depth, bool caustic,
|
||||||
const MediumSamplingRecord &mRec, const Vector &wi,
|
const MediumSamplingRecord &mRec, Float time, const Vector &wi,
|
||||||
const Spectrum &weight);
|
const Spectrum &weight);
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
|
|
||||||
/* Estimate the single scattering component if this is requested */
|
/* Estimate the single scattering component if this is requested */
|
||||||
if (rRec.type & RadianceQueryRecord::EInscatteredDirectRadiance &&
|
if (rRec.type & RadianceQueryRecord::EInscatteredDirectRadiance &&
|
||||||
scene->sampleLuminaireAttenuated(mRec.p, lRec, rRec.nextSample2D())) {
|
scene->sampleLuminaireAttenuated(mRec.p, lRec, ray.time, rRec.nextSample2D())) {
|
||||||
/* Evaluate the phase function */
|
/* Evaluate the phase function */
|
||||||
Spectrum phaseVal = phase->f(mRec, -ray.d, -lRec.d);
|
Spectrum phaseVal = phase->f(mRec, -ray.d, -lRec.d);
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ public:
|
||||||
prevIts = its;
|
prevIts = its;
|
||||||
|
|
||||||
/* Trace a ray in this direction */
|
/* Trace a ray in this direction */
|
||||||
ray = Ray(mRec.p, wo);
|
ray = Ray(mRec.p, wo, ray.time);
|
||||||
bool hitLuminaire = false;
|
bool hitLuminaire = false;
|
||||||
if (scene->rayIntersect(ray, its)) {
|
if (scene->rayIntersect(ray, its)) {
|
||||||
/* Intersected something - check if it was a luminaire */
|
/* Intersected something - check if it was a luminaire */
|
||||||
|
@ -230,7 +230,7 @@ public:
|
||||||
prevIts = its;
|
prevIts = its;
|
||||||
|
|
||||||
/* Trace a ray in this direction */
|
/* Trace a ray in this direction */
|
||||||
ray = Ray(its.p, its.toWorld(bRec.wo));
|
ray = Ray(its.p, its.toWorld(bRec.wo), ray.time);
|
||||||
bool hitLuminaire = false;
|
bool hitLuminaire = false;
|
||||||
if (scene->rayIntersect(ray, its)) {
|
if (scene->rayIntersect(ray, its)) {
|
||||||
/* Intersected something - check if it was a luminaire */
|
/* Intersected something - check if it was a luminaire */
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
|
|
||||||
/* Estimate the single scattering component if this is requested */
|
/* Estimate the single scattering component if this is requested */
|
||||||
if (rRec.type & RadianceQueryRecord::EInscatteredDirectRadiance &&
|
if (rRec.type & RadianceQueryRecord::EInscatteredDirectRadiance &&
|
||||||
scene->sampleLuminaireAttenuated(mRec.p, lRec, rRec.nextSample2D())) {
|
scene->sampleLuminaireAttenuated(mRec.p, lRec, ray.time, rRec.nextSample2D())) {
|
||||||
Li += pathThroughput * lRec.Le * phase->f(mRec, -ray.d, -lRec.d);
|
Li += pathThroughput * lRec.Le * phase->f(mRec, -ray.d, -lRec.d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ public:
|
||||||
prevIts = its;
|
prevIts = its;
|
||||||
|
|
||||||
/* Trace a ray in this direction */
|
/* Trace a ray in this direction */
|
||||||
ray = Ray(mRec.p, wo);
|
ray = Ray(mRec.p, wo, ray.time);
|
||||||
computeIntersection = true;
|
computeIntersection = true;
|
||||||
|
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
|
@ -179,7 +179,7 @@ public:
|
||||||
prevIts = its;
|
prevIts = its;
|
||||||
|
|
||||||
/* Trace a ray in this direction */
|
/* Trace a ray in this direction */
|
||||||
ray = Ray(its.p, its.toWorld(bRec.wo));
|
ray = Ray(its.p, its.toWorld(bRec.wo), ray.time);
|
||||||
computeIntersection = true;
|
computeIntersection = true;
|
||||||
|
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
|
|
|
@ -353,7 +353,7 @@ public:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rRec2.recursiveQuery(rRec, RadianceQueryRecord::ERadiance);
|
rRec2.recursiveQuery(rRec, RadianceQueryRecord::ERadiance);
|
||||||
recursiveRay = Ray(its.p, its.toWorld(bRec.wo));
|
recursiveRay = Ray(its.p, its.toWorld(bRec.wo), ray.time);
|
||||||
Li += m_parentIntegrator->Li(recursiveRay, rRec2) * bsdfVal;
|
Li += m_parentIntegrator->Li(recursiveRay, rRec2) * bsdfVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -370,7 +370,7 @@ public:
|
||||||
Spectrum bsdfVal = bsdf->sampleCos(bRec);
|
Spectrum bsdfVal = bsdf->sampleCos(bRec);
|
||||||
|
|
||||||
rRec2.recursiveQuery(rRec, RadianceQueryRecord::ERadianceNoEmission);
|
rRec2.recursiveQuery(rRec, RadianceQueryRecord::ERadianceNoEmission);
|
||||||
recursiveRay = Ray(its.p, its.toWorld(bRec.wo));
|
recursiveRay = Ray(its.p, its.toWorld(bRec.wo), ray.time);
|
||||||
Li += m_parentIntegrator->Li(recursiveRay, rRec2) * bsdfVal * weight;
|
Li += m_parentIntegrator->Li(recursiveRay, rRec2) * bsdfVal * weight;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -135,9 +135,11 @@ public:
|
||||||
|
|
||||||
m_totalEmitted = 0;
|
m_totalEmitted = 0;
|
||||||
bool needsLensSample = camera->needsLensSample();
|
bool needsLensSample = camera->needsLensSample();
|
||||||
|
bool needsTimeSample = camera->needsTimeSample();
|
||||||
Log(EInfo, "Creating approximately %i gather points", cropSize.x*cropSize.y*sampleCount);
|
Log(EInfo, "Creating approximately %i gather points", cropSize.x*cropSize.y*sampleCount);
|
||||||
Point2 lensSample, sample;
|
Point2 lensSample, sample;
|
||||||
RayDifferential eyeRay;
|
RayDifferential eyeRay;
|
||||||
|
Float timeSample = 0;
|
||||||
m_filter = camera->getFilm()->getTabulatedFilter();
|
m_filter = camera->getFilm()->getTabulatedFilter();
|
||||||
Vector2 filterSize = m_filter->getFilterSize();
|
Vector2 filterSize = m_filter->getFilterSize();
|
||||||
int borderSize = (int) std::ceil(std::max(filterSize.x, filterSize.y));
|
int borderSize = (int) std::ceil(std::max(filterSize.x, filterSize.y));
|
||||||
|
@ -179,10 +181,12 @@ public:
|
||||||
for (uint64_t j = 0; j<sampleCount; j++) {
|
for (uint64_t j = 0; j<sampleCount; j++) {
|
||||||
if (needsLensSample)
|
if (needsLensSample)
|
||||||
lensSample = cameraSampler->next2D();
|
lensSample = cameraSampler->next2D();
|
||||||
|
if (needsTimeSample)
|
||||||
|
timeSample = cameraSampler->next1D();
|
||||||
sample = cameraSampler->next2D();
|
sample = cameraSampler->next2D();
|
||||||
sample.x += x; sample.y += y;
|
sample.x += x; sample.y += y;
|
||||||
camera->generateRayDifferential(sample,
|
camera->generateRayDifferential(sample,
|
||||||
lensSample, eyeRay);
|
lensSample, timeSample, eyeRay);
|
||||||
size_t offset = gatherPoints.size();
|
size_t offset = gatherPoints.size();
|
||||||
int count = createGatherPoints(scene, eyeRay, sample, Spectrum(1.0f),
|
int count = createGatherPoints(scene, eyeRay, sample, Spectrum(1.0f),
|
||||||
gatherPoints, 1);
|
gatherPoints, 1);
|
||||||
|
@ -240,7 +244,7 @@ public:
|
||||||
continue;
|
continue;
|
||||||
bsdfVal = bsdf->fDelta(bRec);
|
bsdfVal = bsdf->fDelta(bRec);
|
||||||
|
|
||||||
RayDifferential recursiveRay(p.its.p, p.its.toWorld(bRec.wo));
|
RayDifferential recursiveRay(p.its.p, p.its.toWorld(bRec.wo), ray.time);
|
||||||
count += createGatherPoints(scene, recursiveRay, sample,
|
count += createGatherPoints(scene, recursiveRay, sample,
|
||||||
weight * bsdfVal, gatherPoints, depth+1);
|
weight * bsdfVal, gatherPoints, depth+1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ public:
|
||||||
void distributedRTPass(Scene *scene, std::vector<SerializableObject *> &samplers) {
|
void distributedRTPass(Scene *scene, std::vector<SerializableObject *> &samplers) {
|
||||||
ref<Camera> camera = scene->getCamera();
|
ref<Camera> camera = scene->getCamera();
|
||||||
bool needsLensSample = camera->needsLensSample();
|
bool needsLensSample = camera->needsLensSample();
|
||||||
|
bool needsTimeSample = camera->needsTimeSample();
|
||||||
ref<Film> film = camera->getFilm();
|
ref<Film> film = camera->getFilm();
|
||||||
Vector2i cropSize = film->getCropSize();
|
Vector2i cropSize = film->getCropSize();
|
||||||
Point2i cropOffset = film->getCropOffset();
|
Point2i cropOffset = film->getCropOffset();
|
||||||
|
@ -192,15 +193,18 @@ public:
|
||||||
if (xofsInt + xofs - cropOffset.x >= cropSize.x)
|
if (xofsInt + xofs - cropOffset.x >= cropSize.x)
|
||||||
continue;
|
continue;
|
||||||
Point2 lensSample, sample;
|
Point2 lensSample, sample;
|
||||||
|
Float timeSample = 0.0f;
|
||||||
GatherPoint &gatherPoint = gatherPoints[index++];
|
GatherPoint &gatherPoint = gatherPoints[index++];
|
||||||
sampler->generate();
|
sampler->generate();
|
||||||
if (needsLensSample)
|
if (needsLensSample)
|
||||||
lensSample = sampler->next2D();
|
lensSample = sampler->next2D();
|
||||||
|
if (needsTimeSample)
|
||||||
|
timeSample = sampler->next1D();
|
||||||
gatherPoint.pos = Point2i(xofs + xofsInt, yofs + yofsInt);
|
gatherPoint.pos = Point2i(xofs + xofsInt, yofs + yofsInt);
|
||||||
sample = sampler->next2D();
|
sample = sampler->next2D();
|
||||||
sample += Vector2((Float) gatherPoint.pos.x, (Float) gatherPoint.pos.y);
|
sample += Vector2((Float) gatherPoint.pos.x, (Float) gatherPoint.pos.y);
|
||||||
RayDifferential ray;
|
RayDifferential ray;
|
||||||
camera->generateRayDifferential(sample, lensSample, ray);
|
camera->generateRayDifferential(sample, lensSample, timeSample, ray);
|
||||||
Spectrum weight(1.0f);
|
Spectrum weight(1.0f);
|
||||||
int depth = 1;
|
int depth = 1;
|
||||||
|
|
||||||
|
@ -232,7 +236,7 @@ public:
|
||||||
gatherPoint.depth = -1;
|
gatherPoint.depth = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ray = RayDifferential(gatherPoint.its.p, gatherPoint.its.toWorld(bRec.wo));
|
ray = RayDifferential(gatherPoint.its.p, gatherPoint.its.toWorld(bRec.wo), ray.time);
|
||||||
++depth;
|
++depth;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -844,7 +844,7 @@ Float SparseWaveletOctree::lineIntegral(Point start, Point end) const {
|
||||||
start /= (Float) m_size;
|
start /= (Float) m_size;
|
||||||
end /= (Float) m_size;
|
end /= (Float) m_size;
|
||||||
|
|
||||||
Ray ray(start, normalize(end-start));
|
Ray ray(start, normalize(end-start), 0.0f);
|
||||||
|
|
||||||
uint8_t a = 0;
|
uint8_t a = 0;
|
||||||
if (ray.d.x < 0) {
|
if (ray.d.x < 0) {
|
||||||
|
|
|
@ -24,8 +24,14 @@ MTS_NAMESPACE_BEGIN
|
||||||
Camera::Camera(const Properties &props)
|
Camera::Camera(const Properties &props)
|
||||||
: ConfigurableObject(props), m_properties(props) {
|
: ConfigurableObject(props), m_properties(props) {
|
||||||
m_cameraToWorld = props.getTransform("toWorld", Transform());
|
m_cameraToWorld = props.getTransform("toWorld", Transform());
|
||||||
|
m_shutterOpen = props.getFloat("shutterOpen", 0.0f);
|
||||||
|
m_shutterClose = props.getFloat("shutterClose", 5.0f);
|
||||||
|
if (m_shutterOpen > m_shutterClose)
|
||||||
|
Log(EError, "Shutter opening time must be less than "
|
||||||
|
"or equal to the shutter closing time!");
|
||||||
m_worldToCamera = m_cameraToWorld.inverse();
|
m_worldToCamera = m_cameraToWorld.inverse();
|
||||||
m_position = m_cameraToWorld(Point(0,0,0));
|
m_position = m_cameraToWorld(Point(0,0,0));
|
||||||
|
m_shutterOpenTime = m_shutterClose - m_shutterOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera::Camera(Stream *stream, InstanceManager *manager)
|
Camera::Camera(Stream *stream, InstanceManager *manager)
|
||||||
|
@ -34,7 +40,10 @@ Camera::Camera(Stream *stream, InstanceManager *manager)
|
||||||
m_sampler = static_cast<Sampler *>(manager->getInstance(stream));
|
m_sampler = static_cast<Sampler *>(manager->getInstance(stream));
|
||||||
m_worldToCamera = Transform(stream);
|
m_worldToCamera = Transform(stream);
|
||||||
m_cameraToWorld = Transform(stream);
|
m_cameraToWorld = Transform(stream);
|
||||||
|
m_shutterOpen = stream->readFloat();
|
||||||
|
m_shutterClose = stream->readFloat();
|
||||||
m_position = m_cameraToWorld(Point(0,0,0));
|
m_position = m_cameraToWorld(Point(0,0,0));
|
||||||
|
m_shutterOpenTime = m_shutterClose - m_shutterOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera::~Camera() {
|
Camera::~Camera() {
|
||||||
|
@ -60,16 +69,18 @@ void Camera::serialize(Stream *stream, InstanceManager *manager) const {
|
||||||
manager->serialize(stream, m_sampler.get());
|
manager->serialize(stream, m_sampler.get());
|
||||||
m_worldToCamera.serialize(stream);
|
m_worldToCamera.serialize(stream);
|
||||||
m_cameraToWorld.serialize(stream);
|
m_cameraToWorld.serialize(stream);
|
||||||
|
stream->writeFloat(m_shutterOpen);
|
||||||
|
stream->writeFloat(m_shutterClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::generateRayDifferential(const Point2 &sample,
|
void Camera::generateRayDifferential(const Point2 &sample,
|
||||||
const Point2 &lensSample, RayDifferential &ray) const {
|
const Point2 &lensSample, Float timeSample, RayDifferential &ray) const {
|
||||||
|
|
||||||
generateRay(sample, lensSample, ray);
|
generateRay(sample, lensSample, timeSample, ray);
|
||||||
Point2 temp = sample; temp.x += 1;
|
Point2 temp = sample; temp.x += 1;
|
||||||
generateRay(temp, lensSample, ray.rx);
|
generateRay(temp, lensSample, timeSample, ray.rx);
|
||||||
temp = sample; temp.y += 1;
|
temp = sample; temp.y += 1;
|
||||||
generateRay(temp, lensSample, ray.ry);
|
generateRay(temp, lensSample, timeSample, ray.ry);
|
||||||
ray.hasDifferentials = true;
|
ray.hasDifferentials = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ void SampleIntegrator::serialize(Stream *stream, InstanceManager *manager) const
|
||||||
stream->writeBool(m_irrIndirect);
|
stream->writeBool(m_irrIndirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum SampleIntegrator::E(const Scene *scene, const Point &p, const Normal &n,
|
Spectrum SampleIntegrator::E(const Scene *scene, const Point &p, const Normal &n, Float time,
|
||||||
Sampler *sampler) const {
|
Sampler *sampler) const {
|
||||||
Spectrum E(0.0f);
|
Spectrum E(0.0f);
|
||||||
LuminaireSamplingRecord lRec;
|
LuminaireSamplingRecord lRec;
|
||||||
|
@ -80,7 +80,7 @@ Spectrum SampleIntegrator::E(const Scene *scene, const Point &p, const Normal &n
|
||||||
rRec.newQuery(RadianceQueryRecord::ERadianceNoEmission);
|
rRec.newQuery(RadianceQueryRecord::ERadianceNoEmission);
|
||||||
|
|
||||||
/* Direct */
|
/* Direct */
|
||||||
if (scene->sampleLuminaireAttenuated(p, lRec, rRec.nextSample2D())) {
|
if (scene->sampleLuminaireAttenuated(p, lRec, time, rRec.nextSample2D())) {
|
||||||
Float dp = dot(lRec.d, n);
|
Float dp = dot(lRec.d, n);
|
||||||
if (dp < 0)
|
if (dp < 0)
|
||||||
E -= lRec.Le * dp;
|
E -= lRec.Le * dp;
|
||||||
|
@ -90,7 +90,7 @@ Spectrum SampleIntegrator::E(const Scene *scene, const Point &p, const Normal &n
|
||||||
if (m_irrIndirect) {
|
if (m_irrIndirect) {
|
||||||
Vector d = frame.toWorld(squareToHemispherePSA(rRec.nextSample2D()));
|
Vector d = frame.toWorld(squareToHemispherePSA(rRec.nextSample2D()));
|
||||||
++rRec.depth;
|
++rRec.depth;
|
||||||
E += Li(RayDifferential(p, d), rRec) * M_PI;
|
E += Li(RayDifferential(p, d, time), rRec) * M_PI;
|
||||||
}
|
}
|
||||||
sampler->advance();
|
sampler->advance();
|
||||||
}
|
}
|
||||||
|
@ -150,6 +150,7 @@ void SampleIntegrator::renderBlock(const Scene *scene,
|
||||||
const Camera *camera, Sampler *sampler, ImageBlock *block, const bool &stop) const {
|
const Camera *camera, Sampler *sampler, ImageBlock *block, const bool &stop) const {
|
||||||
Point2 sample, lensSample;
|
Point2 sample, lensSample;
|
||||||
RayDifferential eyeRay;
|
RayDifferential eyeRay;
|
||||||
|
Float timeSample = 0;
|
||||||
Spectrum spec;
|
Spectrum spec;
|
||||||
int x, y;
|
int x, y;
|
||||||
uint64_t j;
|
uint64_t j;
|
||||||
|
@ -162,6 +163,7 @@ void SampleIntegrator::renderBlock(const Scene *scene,
|
||||||
block->clear();
|
block->clear();
|
||||||
RadianceQueryRecord rRec(scene, sampler);
|
RadianceQueryRecord rRec(scene, sampler);
|
||||||
bool needsLensSample = camera->needsLensSample();
|
bool needsLensSample = camera->needsLensSample();
|
||||||
|
bool needsTimeSample = camera->needsTimeSample();
|
||||||
const TabulatedFilter *filter = camera->getFilm()->getTabulatedFilter();
|
const TabulatedFilter *filter = camera->getFilm()->getTabulatedFilter();
|
||||||
Float scaleFactor = 1.0f/std::sqrt((Float) sampler->getSampleCount());
|
Float scaleFactor = 1.0f/std::sqrt((Float) sampler->getSampleCount());
|
||||||
|
|
||||||
|
@ -175,10 +177,12 @@ void SampleIntegrator::renderBlock(const Scene *scene,
|
||||||
rRec.newQuery(RadianceQueryRecord::ECameraRay);
|
rRec.newQuery(RadianceQueryRecord::ECameraRay);
|
||||||
if (needsLensSample)
|
if (needsLensSample)
|
||||||
lensSample = rRec.nextSample2D();
|
lensSample = rRec.nextSample2D();
|
||||||
|
if (needsTimeSample)
|
||||||
|
timeSample = rRec.nextSample1D();
|
||||||
sample = rRec.nextSample2D();
|
sample = rRec.nextSample2D();
|
||||||
sample.x += x; sample.y += y;
|
sample.x += x; sample.y += y;
|
||||||
camera->generateRayDifferential(sample,
|
camera->generateRayDifferential(sample,
|
||||||
lensSample, eyeRay);
|
lensSample, timeSample, eyeRay);
|
||||||
eyeRay.scaleDifferential(scaleFactor);
|
eyeRay.scaleDifferential(scaleFactor);
|
||||||
++cameraRays;
|
++cameraRays;
|
||||||
spec = Li(eyeRay, rRec);
|
spec = Li(eyeRay, rRec);
|
||||||
|
@ -199,10 +203,12 @@ void SampleIntegrator::renderBlock(const Scene *scene,
|
||||||
rRec.newQuery(RadianceQueryRecord::ECameraRay);
|
rRec.newQuery(RadianceQueryRecord::ECameraRay);
|
||||||
if (needsLensSample)
|
if (needsLensSample)
|
||||||
lensSample = rRec.nextSample2D();
|
lensSample = rRec.nextSample2D();
|
||||||
|
if (needsTimeSample)
|
||||||
|
timeSample = rRec.nextSample1D();
|
||||||
sample = rRec.nextSample2D();
|
sample = rRec.nextSample2D();
|
||||||
sample.x += x; sample.y += y;
|
sample.x += x; sample.y += y;
|
||||||
camera->generateRayDifferential(sample,
|
camera->generateRayDifferential(sample,
|
||||||
lensSample, eyeRay);
|
lensSample, timeSample, eyeRay);
|
||||||
eyeRay.scaleDifferential(scaleFactor);
|
eyeRay.scaleDifferential(scaleFactor);
|
||||||
++cameraRays;
|
++cameraRays;
|
||||||
spec = Li(eyeRay, rRec);
|
spec = Li(eyeRay, rRec);
|
||||||
|
|
|
@ -86,6 +86,7 @@ std::string Intersection::toString() const {
|
||||||
<< " uv = " << uv.toString() << "," << std::endl
|
<< " uv = " << uv.toString() << "," << std::endl
|
||||||
<< " dpdu = " << dpdu.toString() << "," << std::endl
|
<< " dpdu = " << dpdu.toString() << "," << std::endl
|
||||||
<< " dpdv = " << dpdv.toString() << "," << std::endl
|
<< " dpdv = " << dpdv.toString() << "," << std::endl
|
||||||
|
<< " time = " << time << "," << std::endl
|
||||||
<< " shape = " << indent(((Object *)shape)->toString()) << std::endl
|
<< " shape = " << indent(((Object *)shape)->toString()) << std::endl
|
||||||
<< "]";
|
<< "]";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
|
|
|
@ -262,7 +262,7 @@ inline int new_node(Float t1, int a, Float t2, int b, Float t3, int c) {
|
||||||
Float SparseMipmap3D::lineIntegral(const Ray &r) const {
|
Float SparseMipmap3D::lineIntegral(const Ray &r) const {
|
||||||
Float length = r.d.length();
|
Float length = r.d.length();
|
||||||
|
|
||||||
Ray ray(r(r.mint), r.d/length, 0, (r.maxt-r.mint)*length);
|
Ray ray(r(r.mint), r.d/length, 0, (r.maxt-r.mint)*length, 0.0f);
|
||||||
|
|
||||||
uint8_t a = 0;
|
uint8_t a = 0;
|
||||||
if (ray.d.x < 0) {
|
if (ray.d.x < 0) {
|
||||||
|
@ -304,7 +304,7 @@ bool SparseMipmap3D::invertLineIntegral(const Ray &r, Float desiredDensity,
|
||||||
Float &accumDensity, Float &samplePos, Float &sampleDensity) const {
|
Float &accumDensity, Float &samplePos, Float &sampleDensity) const {
|
||||||
Float length = r.d.length();
|
Float length = r.d.length();
|
||||||
|
|
||||||
Ray ray(r(r.mint), r.d/length, 0, (r.maxt-r.mint)*length);
|
Ray ray(r(r.mint), r.d/length, 0, (r.maxt-r.mint)*length, 0.0f);
|
||||||
|
|
||||||
uint8_t a = 0;
|
uint8_t a = 0;
|
||||||
if (ray.d.x < 0) {
|
if (ray.d.x < 0) {
|
||||||
|
|
|
@ -98,6 +98,9 @@ void ParticleTracer::process(const WorkUnit *workUnit, WorkResult *workResult,
|
||||||
Spectrum weight, bsdfVal;
|
Spectrum weight, bsdfVal;
|
||||||
int depth;
|
int depth;
|
||||||
bool caustic;
|
bool caustic;
|
||||||
|
ref<Camera> camera = m_scene->getCamera();
|
||||||
|
Float shutterOpen = camera->getShutterOpen(),
|
||||||
|
shutterOpenTime = camera->getShutterOpenTime();
|
||||||
|
|
||||||
m_sampler->generate();
|
m_sampler->generate();
|
||||||
for (size_t index = range->getRangeStart(); index <= range->getRangeEnd() && !stop; ++index) {
|
for (size_t index = range->getRangeStart(); index <= range->getRangeEnd() && !stop; ++index) {
|
||||||
|
@ -108,7 +111,7 @@ void ParticleTracer::process(const WorkUnit *workUnit, WorkResult *workResult,
|
||||||
/* Sample an emitted particle */
|
/* Sample an emitted particle */
|
||||||
m_scene->sampleEmission(eRec, areaSample, dirSample);
|
m_scene->sampleEmission(eRec, areaSample, dirSample);
|
||||||
|
|
||||||
ray = Ray(eRec.sRec.p, eRec.d);
|
ray = Ray(eRec.sRec.p, eRec.d, shutterOpen + shutterOpenTime * m_sampler->next1D());
|
||||||
weight = eRec.P;
|
weight = eRec.P;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
caustic = true;
|
caustic = true;
|
||||||
|
@ -126,7 +129,7 @@ void ParticleTracer::process(const WorkUnit *workUnit, WorkResult *workResult,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
weight *= mRec.sigmaS * mRec.attenuation / mRec.pdf;
|
weight *= mRec.sigmaS * mRec.attenuation / mRec.pdf;
|
||||||
handleMediumInteraction(depth, caustic, mRec, -ray.d, weight);
|
handleMediumInteraction(depth, caustic, mRec, ray.time, -ray.d, weight);
|
||||||
|
|
||||||
if (!m_multipleScattering)
|
if (!m_multipleScattering)
|
||||||
break;
|
break;
|
||||||
|
@ -144,7 +147,7 @@ void ParticleTracer::process(const WorkUnit *workUnit, WorkResult *workResult,
|
||||||
weight /= mRec.albedo;
|
weight /= mRec.albedo;
|
||||||
}
|
}
|
||||||
|
|
||||||
ray = Ray(mRec.p, wo);
|
ray = Ray(mRec.p, wo, ray.time);
|
||||||
} else if (its.t == std::numeric_limits<Float>::infinity()) {
|
} else if (its.t == std::numeric_limits<Float>::infinity()) {
|
||||||
/* There is no surface in this direction */
|
/* There is no surface in this direction */
|
||||||
break;
|
break;
|
||||||
|
@ -179,7 +182,7 @@ void ParticleTracer::process(const WorkUnit *workUnit, WorkResult *workResult,
|
||||||
|
|
||||||
weight *= bsdfVal;
|
weight *= bsdfVal;
|
||||||
Vector wi = -ray.d, wo = its.toWorld(bRec.wo);
|
Vector wi = -ray.d, wo = its.toWorld(bRec.wo);
|
||||||
ray = Ray(its.p, wo);
|
ray = Ray(its.p, wo, ray.time);
|
||||||
|
|
||||||
/* Prevent light leaks due to the use of shading normals -- [Veach, p. 158] */
|
/* Prevent light leaks due to the use of shading normals -- [Veach, p. 158] */
|
||||||
Float wiDotGeoN = dot(its.geoFrame.n, wi),
|
Float wiDotGeoN = dot(its.geoFrame.n, wi),
|
||||||
|
@ -206,7 +209,7 @@ void ParticleTracer::handleSurfaceInteraction(int depth, bool caustic,
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleTracer::handleMediumInteraction(int depth, bool caustic,
|
void ParticleTracer::handleMediumInteraction(int depth, bool caustic,
|
||||||
const MediumSamplingRecord &mRec, const Vector &wi,
|
const MediumSamplingRecord &mRec, Float time, const Vector &wi,
|
||||||
const Spectrum &weight) {
|
const Spectrum &weight) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ void PreviewWorker::processIncoherent(const WorkUnit *workUnit, WorkResult *work
|
||||||
/* Generate a camera ray without normalization */
|
/* Generate a camera ray without normalization */
|
||||||
primary = Ray(m_cameraO, m_cameraTL
|
primary = Ray(m_cameraO, m_cameraTL
|
||||||
+ m_cameraDx * (Float) x
|
+ m_cameraDx * (Float) x
|
||||||
+ m_cameraDy * (Float) y);
|
+ m_cameraDy * (Float) y, 0.0f);
|
||||||
|
|
||||||
++numRays;
|
++numRays;
|
||||||
if (!m_kdtree->rayIntersect(primary, its)) {
|
if (!m_kdtree->rayIntersect(primary, its)) {
|
||||||
|
@ -88,7 +88,7 @@ void PreviewWorker::processIncoherent(const WorkUnit *workUnit, WorkResult *work
|
||||||
value = Spectrum(0.0f);
|
value = Spectrum(0.0f);
|
||||||
|
|
||||||
toVPL = m_vpl.its.p - its.p;
|
toVPL = m_vpl.its.p - its.p;
|
||||||
secondary = Ray(its.p, toVPL, ShadowEpsilon, 1-ShadowEpsilon);
|
secondary = Ray(its.p, toVPL, ShadowEpsilon, 1-ShadowEpsilon, 0.0f);
|
||||||
++numRays;
|
++numRays;
|
||||||
if (m_kdtree->rayIntersect(secondary)) {
|
if (m_kdtree->rayIntersect(secondary)) {
|
||||||
block->setPixel(pos++, value);
|
block->setPixel(pos++, value);
|
||||||
|
@ -281,7 +281,8 @@ void PreviewWorker::processCoherent(const WorkUnit *workUnit, WorkResult *workRe
|
||||||
secItv4.maxt.f[idx] = 0;
|
secItv4.maxt.f[idx] = 0;
|
||||||
emitted[idx] = m_scene->LeBackground(Ray(
|
emitted[idx] = m_scene->LeBackground(Ray(
|
||||||
Point(primRay4.o[0].f[idx], primRay4.o[1].f[idx], primRay4.o[2].f[idx]),
|
Point(primRay4.o[0].f[idx], primRay4.o[1].f[idx], primRay4.o[2].f[idx]),
|
||||||
Vector(primRay4.d[0].f[idx], primRay4.d[1].f[idx], primRay4.d[2].f[idx])
|
Vector(primRay4.d[0].f[idx], primRay4.d[1].f[idx], primRay4.d[2].f[idx]),
|
||||||
|
0.0f
|
||||||
));
|
));
|
||||||
memset(&direct[idx], 0, sizeof(Spectrum));
|
memset(&direct[idx], 0, sizeof(Spectrum));
|
||||||
continue;
|
continue;
|
||||||
|
@ -346,7 +347,8 @@ void PreviewWorker::processCoherent(const WorkUnit *workUnit, WorkResult *workRe
|
||||||
} else {
|
} else {
|
||||||
Ray ray(
|
Ray ray(
|
||||||
Point(primRay4.o[0].f[idx], primRay4.o[1].f[idx], primRay4.o[2].f[idx]),
|
Point(primRay4.o[0].f[idx], primRay4.o[1].f[idx], primRay4.o[2].f[idx]),
|
||||||
Vector(primRay4.d[0].f[idx], primRay4.d[1].f[idx], primRay4.d[2].f[idx])
|
Vector(primRay4.d[0].f[idx], primRay4.d[1].f[idx], primRay4.d[2].f[idx]),
|
||||||
|
0.0f
|
||||||
);
|
);
|
||||||
its.t = its4.t.f[idx];
|
its.t = its4.t.f[idx];
|
||||||
shape->fillIntersectionRecord(ray, temp + idx * MTS_KD_INTERSECTION_TEMP + 8, its);
|
shape->fillIntersectionRecord(ray, temp + idx * MTS_KD_INTERSECTION_TEMP + 8, its);
|
||||||
|
|
|
@ -383,7 +383,7 @@ Float Scene::pdfLuminaire(const Intersection &its,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scene::sampleLuminaire(const Point &p,
|
bool Scene::sampleLuminaire(const Point &p,
|
||||||
LuminaireSamplingRecord &lRec, const Point2 &s,
|
LuminaireSamplingRecord &lRec, Float time, const Point2 &s,
|
||||||
bool testVisibility) const {
|
bool testVisibility) const {
|
||||||
Point2 sample(s);
|
Point2 sample(s);
|
||||||
Float lumPdf;
|
Float lumPdf;
|
||||||
|
@ -392,7 +392,7 @@ bool Scene::sampleLuminaire(const Point &p,
|
||||||
luminaire->sample(p, lRec, sample);
|
luminaire->sample(p, lRec, sample);
|
||||||
|
|
||||||
if (lRec.pdf != 0) {
|
if (lRec.pdf != 0) {
|
||||||
if (testVisibility && isOccluded(p, lRec.sRec.p))
|
if (testVisibility && isOccluded(p, lRec.sRec.p, time))
|
||||||
return false;
|
return false;
|
||||||
lRec.pdf *= lumPdf;
|
lRec.pdf *= lumPdf;
|
||||||
lRec.Le /= lRec.pdf;
|
lRec.Le /= lRec.pdf;
|
||||||
|
@ -413,7 +413,7 @@ bool Scene::sampleLuminaire(const Intersection &its,
|
||||||
luminaire->sample(its, lRec, sample);
|
luminaire->sample(its, lRec, sample);
|
||||||
|
|
||||||
if (lRec.pdf != 0) {
|
if (lRec.pdf != 0) {
|
||||||
if (testVisibility && isOccluded(its.p, lRec.sRec.p))
|
if (testVisibility && isOccluded(its.p, lRec.sRec.p, its.time))
|
||||||
return false;
|
return false;
|
||||||
lRec.pdf *= lumPdf;
|
lRec.pdf *= lumPdf;
|
||||||
lRec.Le /= lRec.pdf;
|
lRec.Le /= lRec.pdf;
|
||||||
|
|
|
@ -93,8 +93,6 @@ void AnimatedTransform::eval(Float t, Transform &trafo) const {
|
||||||
"animation track type: %i!", track->getType());
|
"animation track type: %i!", track->getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//cout << "T:" << translation.toString() << " R:" << rotation.toString() << " S:" << scale.toString() << endl;
|
|
||||||
|
|
||||||
trafo = Transform::translate(translation) *
|
trafo = Transform::translate(translation) *
|
||||||
rotation.toTransform() *
|
rotation.toTransform() *
|
||||||
Transform::scale(scale);
|
Transform::scale(scale);
|
||||||
|
|
|
@ -55,7 +55,7 @@ size_t generateVPLs(const Scene *scene, size_t offset, size_t count, int maxDept
|
||||||
weight *= scene->sampleEmissionDirection(eRec, dirSample);
|
weight *= scene->sampleEmissionDirection(eRec, dirSample);
|
||||||
Float cosTheta = (eRec.luminaire->getType() & Luminaire::EOnSurface) ? absDot(eRec.sRec.n, eRec.d) : 1;
|
Float cosTheta = (eRec.luminaire->getType() & Luminaire::EOnSurface) ? absDot(eRec.sRec.n, eRec.d) : 1;
|
||||||
weight *= cosTheta / eRec.pdfDir;
|
weight *= cosTheta / eRec.pdfDir;
|
||||||
ray = Ray(eRec.sRec.p, eRec.d);
|
ray = Ray(eRec.sRec.p, eRec.d, 0.0f);
|
||||||
|
|
||||||
depth = 2;
|
depth = 2;
|
||||||
while (!weight.isBlack() && depth < maxDepth) {
|
while (!weight.isBlack() && depth < maxDepth) {
|
||||||
|
@ -85,7 +85,7 @@ size_t generateVPLs(const Scene *scene, size_t offset, size_t count, int maxDept
|
||||||
weight *= bsdfVal;
|
weight *= bsdfVal;
|
||||||
|
|
||||||
Vector wi = -ray.d, wo = its.toWorld(bRec.wo);
|
Vector wi = -ray.d, wo = its.toWorld(bRec.wo);
|
||||||
ray = Ray(its.p, wo);
|
ray = Ray(its.p, wo, 0.0f);
|
||||||
|
|
||||||
/* Prevent light leaks due to the use of shading normals -- [Veach, p. 158] */
|
/* Prevent light leaks due to the use of shading normals -- [Veach, p. 158] */
|
||||||
Float wiDotGeoN = dot(its.geoFrame.n, wi),
|
Float wiDotGeoN = dot(its.geoFrame.n, wi),
|
||||||
|
|
|
@ -377,7 +377,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInside(const Ray &r) const {
|
bool isInside(const Ray &r) const {
|
||||||
Ray ray(r(r.mint + Epsilon), r.d);
|
Ray ray(r(r.mint + Epsilon), r.d, 0.0f);
|
||||||
Intersection its;
|
Intersection its;
|
||||||
if (!m_kdTree->rayIntersect(ray, its))
|
if (!m_kdTree->rayIntersect(ray, its))
|
||||||
return false;
|
return false;
|
||||||
|
@ -386,7 +386,7 @@ public:
|
||||||
|
|
||||||
Spectrum tau(const Ray &r) const {
|
Spectrum tau(const Ray &r) const {
|
||||||
Float dLength = r.d.length();
|
Float dLength = r.d.length();
|
||||||
Ray ray(r(r.mint), r.d / dLength);
|
Ray ray(r(r.mint), r.d / dLength, 0.0f);
|
||||||
Float coveredLength = 0, remaining = (r.maxt - r.mint) * dLength;
|
Float coveredLength = 0, remaining = (r.maxt - r.mint) * dLength;
|
||||||
bool inside = isInside(r);
|
bool inside = isInside(r);
|
||||||
Intersection its;
|
Intersection its;
|
||||||
|
@ -416,7 +416,7 @@ public:
|
||||||
bool sampleDistance(const Ray &theRay, Float distSurf,
|
bool sampleDistance(const Ray &theRay, Float distSurf,
|
||||||
MediumSamplingRecord &mRec, Sampler *sampler) const {
|
MediumSamplingRecord &mRec, Sampler *sampler) const {
|
||||||
Intersection its;
|
Intersection its;
|
||||||
Ray ray(theRay.o, theRay.d);
|
Ray ray(theRay.o, theRay.d, 0.0f);
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
|
|
||||||
/* Check if the start of the ray is already inside the medium */
|
/* Check if the start of the ray is already inside the medium */
|
||||||
|
|
|
@ -364,7 +364,7 @@ public:
|
||||||
|
|
||||||
Spectrum tau(const Ray &r) const {
|
Spectrum tau(const Ray &r) const {
|
||||||
Float dLength = r.d.length();
|
Float dLength = r.d.length();
|
||||||
Ray ray(r(r.mint), r.d / dLength);
|
Ray ray(r(r.mint), r.d / dLength, 0.0f);
|
||||||
Float remaining = (r.maxt - r.mint) * dLength;
|
Float remaining = (r.maxt - r.mint) * dLength;
|
||||||
Float integral = 0.0f;
|
Float integral = 0.0f;
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
|
@ -462,7 +462,7 @@ public:
|
||||||
bool sampleDistance(const Ray &r, Float maxDist,
|
bool sampleDistance(const Ray &r, Float maxDist,
|
||||||
MediumSamplingRecord &mRec, Sampler *sampler) const {
|
MediumSamplingRecord &mRec, Sampler *sampler) const {
|
||||||
Float dLength = r.d.length();
|
Float dLength = r.d.length();
|
||||||
Ray ray(r(r.mint), r.d / dLength);
|
Ray ray(r(r.mint), r.d / dLength, 0.0f);
|
||||||
Float remaining = (maxDist - r.mint) * dLength,
|
Float remaining = (maxDist - r.mint) * dLength,
|
||||||
desiredTau = -std::log(1-sampler->next1D())/m_sizeMultiplier,
|
desiredTau = -std::log(1-sampler->next1D())/m_sizeMultiplier,
|
||||||
accumulatedTau = 0.0f,
|
accumulatedTau = 0.0f,
|
||||||
|
|
|
@ -168,7 +168,7 @@ public:
|
||||||
|
|
||||||
Spectrum tau(const Ray &r) const {
|
Spectrum tau(const Ray &r) const {
|
||||||
Float dLength = r.d.length();
|
Float dLength = r.d.length();
|
||||||
Ray ray(r(r.mint), r.d / dLength);
|
Ray ray(r(r.mint), r.d / dLength, 0.0f);
|
||||||
Float remaining = (r.maxt - r.mint) * dLength;
|
Float remaining = (r.maxt - r.mint) * dLength;
|
||||||
Float integral = 0.0f;
|
Float integral = 0.0f;
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
|
@ -266,7 +266,7 @@ public:
|
||||||
bool sampleDistance(const Ray &r, Float maxDist,
|
bool sampleDistance(const Ray &r, Float maxDist,
|
||||||
MediumSamplingRecord &mRec, Sampler *sampler) const {
|
MediumSamplingRecord &mRec, Sampler *sampler) const {
|
||||||
Float dLength = r.d.length();
|
Float dLength = r.d.length();
|
||||||
Ray ray(r(r.mint), r.d / dLength);
|
Ray ray(r(r.mint), r.d / dLength, 0.0f);
|
||||||
Float remaining = (maxDist - r.mint) * dLength,
|
Float remaining = (maxDist - r.mint) * dLength,
|
||||||
desiredTau = -std::log(1-sampler->next1D())/m_sizeMultiplier,
|
desiredTau = -std::log(1-sampler->next1D())/m_sizeMultiplier,
|
||||||
accumulatedTau = 0.0f,
|
accumulatedTau = 0.0f,
|
||||||
|
|
|
@ -112,7 +112,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInside(const Ray &r) const {
|
bool isInside(const Ray &r) const {
|
||||||
Ray ray(r(r.mint + Epsilon), r.d);
|
Ray ray(r(r.mint + Epsilon), r.d, 0.0f);
|
||||||
Intersection its;
|
Intersection its;
|
||||||
if (!m_kdTree->rayIntersect(ray, its))
|
if (!m_kdTree->rayIntersect(ray, its))
|
||||||
return false;
|
return false;
|
||||||
|
@ -121,7 +121,7 @@ public:
|
||||||
|
|
||||||
Spectrum tau(const Ray &r) const {
|
Spectrum tau(const Ray &r) const {
|
||||||
Float dLength = r.d.length();
|
Float dLength = r.d.length();
|
||||||
Ray ray(r(r.mint), r.d / dLength, Epsilon, std::numeric_limits<Float>::infinity());
|
Ray ray(r(r.mint), r.d / dLength, Epsilon, std::numeric_limits<Float>::infinity(), 0.0f);
|
||||||
Float coveredLength = 0, remaining = (r.maxt - r.mint) * dLength;
|
Float coveredLength = 0, remaining = (r.maxt - r.mint) * dLength;
|
||||||
bool inside = isInside(r);
|
bool inside = isInside(r);
|
||||||
Intersection its;
|
Intersection its;
|
||||||
|
@ -147,7 +147,7 @@ public:
|
||||||
bool sampleDistance(const Ray &theRay, Float distSurf,
|
bool sampleDistance(const Ray &theRay, Float distSurf,
|
||||||
MediumSamplingRecord &mRec, Sampler *sampler) const {
|
MediumSamplingRecord &mRec, Sampler *sampler) const {
|
||||||
Intersection its;
|
Intersection its;
|
||||||
Ray ray(theRay.o, theRay.d);
|
Ray ray(theRay.o, theRay.d, 0.0f);
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
|
|
||||||
/* Check if the start of the ray is already inside the medium */
|
/* Check if the start of the ray is already inside the medium */
|
||||||
|
|
|
@ -92,11 +92,12 @@ void PreviewProcess::configure(const VPL &vpl, Float minDist, const Point2 &jitt
|
||||||
const Point2 right(topLeft.x + m_film->getSize().x, topLeft.y);
|
const Point2 right(topLeft.x + m_film->getSize().x, topLeft.y);
|
||||||
const Point2 bottom(topLeft.x, topLeft.y + m_film->getSize().y);
|
const Point2 bottom(topLeft.x, topLeft.y + m_film->getSize().y);
|
||||||
const Point2 lens(0, 0);
|
const Point2 lens(0, 0);
|
||||||
|
Float time = 0.0f;
|
||||||
|
|
||||||
const Camera *camera = m_scene->getCamera();
|
const Camera *camera = m_scene->getCamera();
|
||||||
camera->generateRay(topLeft, lens, topLeftRay);
|
camera->generateRay(topLeft, lens, time, topLeftRay);
|
||||||
camera->generateRay(right, lens, rightRay);
|
camera->generateRay(right, lens, time, rightRay);
|
||||||
camera->generateRay(bottom, lens, bottomRay);
|
camera->generateRay(bottom, lens, time, bottomRay);
|
||||||
m_cameraTL = Vector(topLeftRay.d);
|
m_cameraTL = Vector(topLeftRay.d);
|
||||||
m_cameraO = camera->getPosition();
|
m_cameraO = camera->getPosition();
|
||||||
m_cameraDx = (rightRay.d - topLeftRay.d)
|
m_cameraDx = (rightRay.d - topLeftRay.d)
|
||||||
|
|
|
@ -23,8 +23,6 @@
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
#define TIME 0
|
|
||||||
|
|
||||||
class AnimatedInstance : public Shape {
|
class AnimatedInstance : public Shape {
|
||||||
public:
|
public:
|
||||||
AnimatedInstance(const Properties &props) : Shape(props) {
|
AnimatedInstance(const Properties &props) : Shape(props) {
|
||||||
|
@ -96,7 +94,7 @@ public:
|
||||||
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
||||||
Ray ray;
|
Ray ray;
|
||||||
Transform objectToWorld, worldToObject;
|
Transform objectToWorld, worldToObject;
|
||||||
m_transform->eval(TIME, objectToWorld);
|
m_transform->eval(_ray.time, objectToWorld);
|
||||||
worldToObject = objectToWorld.inverse();
|
worldToObject = objectToWorld.inverse();
|
||||||
worldToObject(_ray, ray);
|
worldToObject(_ray, ray);
|
||||||
return kdtree->rayIntersect(ray, mint, maxt, t, temp);
|
return kdtree->rayIntersect(ray, mint, maxt, t, temp);
|
||||||
|
@ -106,7 +104,7 @@ public:
|
||||||
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
||||||
Ray ray;
|
Ray ray;
|
||||||
Transform objectToWorld, worldToObject;
|
Transform objectToWorld, worldToObject;
|
||||||
m_transform->eval(TIME, objectToWorld);
|
m_transform->eval(_ray.time, objectToWorld);
|
||||||
worldToObject = objectToWorld.inverse();
|
worldToObject = objectToWorld.inverse();
|
||||||
worldToObject(_ray, ray);
|
worldToObject(_ray, ray);
|
||||||
return kdtree->rayIntersect(ray, mint, maxt);
|
return kdtree->rayIntersect(ray, mint, maxt);
|
||||||
|
@ -116,7 +114,7 @@ public:
|
||||||
const void *temp, Intersection &its) const {
|
const void *temp, Intersection &its) const {
|
||||||
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
||||||
Transform objectToWorld;
|
Transform objectToWorld;
|
||||||
m_transform->eval(TIME, objectToWorld);
|
m_transform->eval(ray.time, objectToWorld);
|
||||||
kdtree->fillIntersectionRecord<false>(ray, temp, its);
|
kdtree->fillIntersectionRecord<false>(ray, temp, its);
|
||||||
its.shFrame.n = normalize(objectToWorld(its.shFrame.n));
|
its.shFrame.n = normalize(objectToWorld(its.shFrame.n));
|
||||||
its.shFrame.s = normalize(objectToWorld(its.shFrame.s));
|
its.shFrame.s = normalize(objectToWorld(its.shFrame.s));
|
||||||
|
|
|
@ -209,7 +209,7 @@ public:
|
||||||
Vector d = Frame(w*invDistW).toWorld(
|
Vector d = Frame(w*invDistW).toWorld(
|
||||||
squareToCone(cosThetaMax, sample));
|
squareToCone(cosThetaMax, sample));
|
||||||
|
|
||||||
Ray ray(p, d);
|
Ray ray(p, d, 0.0f);
|
||||||
Float t;
|
Float t;
|
||||||
if (!rayIntersect(ray, 0, std::numeric_limits<Float>::infinity(), t, NULL)) {
|
if (!rayIntersect(ray, 0, std::numeric_limits<Float>::infinity(), t, NULL)) {
|
||||||
// This can happen sometimes due to roundoff errors - just fail to
|
// This can happen sometimes due to roundoff errors - just fail to
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
const RangeWorkUnit *range = static_cast<const RangeWorkUnit *>(workUnit);
|
const RangeWorkUnit *range = static_cast<const RangeWorkUnit *>(workUnit);
|
||||||
IrradianceRecordVector *result = static_cast<IrradianceRecordVector *>(workResult);
|
IrradianceRecordVector *result = static_cast<IrradianceRecordVector *>(workResult);
|
||||||
const SampleIntegrator *integrator = m_integrator.get();
|
const SampleIntegrator *integrator = m_integrator.get();
|
||||||
|
ref<Camera> camera = m_scene->getCamera();
|
||||||
|
|
||||||
result->clear();
|
result->clear();
|
||||||
for (size_t i=range->getRangeStart(); i<range->getRangeEnd(); ++i) {
|
for (size_t i=range->getRangeStart(); i<range->getRangeEnd(); ++i) {
|
||||||
|
@ -83,10 +84,11 @@ public:
|
||||||
expSamples *= m_sampleCount;
|
expSamples *= m_sampleCount;
|
||||||
ShapeSamplingRecord sRec;
|
ShapeSamplingRecord sRec;
|
||||||
Float pdf = m_shapes[index]->sampleArea(sRec, sample) * expSamples;
|
Float pdf = m_shapes[index]->sampleArea(sRec, sample) * expSamples;
|
||||||
|
Float time = camera->getShutterOpen() + m_sampler->next1D() * camera->getShutterOpenTime();
|
||||||
|
|
||||||
result->put(IrradianceSample(
|
result->put(IrradianceSample(
|
||||||
sRec.p,
|
sRec.p,
|
||||||
integrator->E(m_scene.get(), sRec.p, sRec.n, m_independentSampler),
|
integrator->E(m_scene.get(), sRec.p, sRec.n, time, m_independentSampler),
|
||||||
1/pdf
|
1/pdf
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ public:
|
||||||
sample2(random->nextFloat(), random->nextFloat());
|
sample2(random->nextFloat(), random->nextFloat());
|
||||||
Point p1 = bsphere.center + squareToSphere(sample1) * bsphere.radius;
|
Point p1 = bsphere.center + squareToSphere(sample1) * bsphere.radius;
|
||||||
Point p2 = bsphere.center + squareToSphere(sample2) * bsphere.radius;
|
Point p2 = bsphere.center + squareToSphere(sample2) * bsphere.radius;
|
||||||
Ray r(p1, normalize(p2-p1));
|
Ray r(p1, normalize(p2-p1), 0.0f);
|
||||||
Intersection its;
|
Intersection its;
|
||||||
|
|
||||||
if (tree->rayIntersect(r))
|
if (tree->rayIntersect(r))
|
||||||
|
|
|
@ -225,7 +225,7 @@ public:
|
||||||
sample2(random->nextFloat(), random->nextFloat());
|
sample2(random->nextFloat(), random->nextFloat());
|
||||||
Point p1 = bsphere.center + squareToSphere(sample1) * bsphere.radius;
|
Point p1 = bsphere.center + squareToSphere(sample1) * bsphere.radius;
|
||||||
Point p2 = bsphere.center + squareToSphere(sample2) * bsphere.radius;
|
Point p2 = bsphere.center + squareToSphere(sample2) * bsphere.radius;
|
||||||
Ray r(p1, normalize(p2-p1));
|
Ray r(p1, normalize(p2-p1), 0.0f);
|
||||||
|
|
||||||
Intersection its;
|
Intersection its;
|
||||||
if (kdtree->rayIntersect(r, its))
|
if (kdtree->rayIntersect(r, its))
|
||||||
|
|
Loading…
Reference in New Issue