diff --git a/src/pbrt/base/material.h b/src/pbrt/base/material.h index b9b89be268e5bee3d66a35062f780f184ac68294..16fe1e877b5ce6cb935548817e5a3600ffe37eab 100644 --- a/src/pbrt/base/material.h +++ b/src/pbrt/base/material.h @@ -54,13 +54,13 @@ class MaterialHandle template PBRT_CPU_GPU inline BSDF GetBSDF(TextureEvaluator texEval, MaterialEvalContext ctx, SampledWavelengths &lambda, - ScratchBuffer &scratchBuffer) const; + ScratchBuffer &buf) const; template PBRT_CPU_GPU inline BSSRDFHandle GetBSSRDF(TextureEvaluator texEval, MaterialEvalContext ctx, SampledWavelengths &lambda, - ScratchBuffer &scratchBuffer) const; + ScratchBuffer &buf) const; PBRT_CPU_GPU inline FloatTextureHandle GetDisplacement() const; diff --git a/src/pbrt/base/texture.h b/src/pbrt/base/texture.h index ed1c04cd7bdf8ba4cc6c093715766d0f5cc60514..5a615269cf8ee2c246f7005f4f6606cedbd42d80 100644 --- a/src/pbrt/base/texture.h +++ b/src/pbrt/base/texture.h @@ -30,10 +30,12 @@ class WrinkledTexture; // FloatTextureHandle Definition class FloatTextureHandle - : public TaggedPointer { + : public TaggedPointer< // FloatTextures + FloatImageTexture, GPUFloatImageTexture, FloatMixTexture, FloatScaledTexture, + FloatConstantTexture, FloatBilerpTexture, FloatCheckerboardTexture, + FloatDotsTexture, FBmTexture, FloatPtexTexture, WindyTexture, WrinkledTexture + + > { public: // FloatTexture Interface using TaggedPointer::TaggedPointer; @@ -63,11 +65,13 @@ class SpectrumScaledTexture; // SpectrumTextureHandle Definition class SpectrumTextureHandle - : public TaggedPointer< - RGBConstantTexture, RGBReflectanceConstantTexture, SpectrumImageTexture, - GPUSpectrumImageTexture, SpectrumMixTexture, SpectrumScaledTexture, - SpectrumConstantTexture, SpectrumBilerpTexture, SpectrumCheckerboardTexture, - MarbleTexture, SpectrumDotsTexture, SpectrumPtexTexture> { + : public TaggedPointer< // SpectrumTextures + SpectrumImageTexture, GPUSpectrumImageTexture, SpectrumMixTexture, + SpectrumScaledTexture, SpectrumConstantTexture, SpectrumBilerpTexture, + SpectrumCheckerboardTexture, MarbleTexture, SpectrumDotsTexture, + SpectrumPtexTexture + + > { public: // SpectrumTexture Interface using TaggedPointer::TaggedPointer; diff --git a/src/pbrt/cameras.cpp b/src/pbrt/cameras.cpp index d544c337818c67b9907c1f77d28f113456900314..f5b3775bc9f67564503a3e7bc42748925926f0af 100644 --- a/src/pbrt/cameras.cpp +++ b/src/pbrt/cameras.cpp @@ -157,21 +157,32 @@ pstd::optional CameraBase::GenerateRayDifferential( } void CameraBase::ApproximatedPdxy(SurfaceInteraction &si, int samplesPerPixel) const { - Point3f pc = CameraFromRender(si.p(), si.time); - Float dist = Distance(pc, Point3f(0, 0, 0)); - + // Compute tangent plane equation for ray differential intersections + Point3f pCamera = CameraFromRender(si.p(), si.time); + Normal3f nCamera = CameraFromRender(si.n, si.time); + Transform DownZFromCamera = + RotateFromTo(Normalize(Vector3f(pCamera)), Vector3f(0, 0, 1)); + Point3f pDownZ = DownZFromCamera(pCamera); + Normal3f nDownZ = DownZFromCamera(nCamera); + Float d = Dot(nDownZ, Vector3f(pDownZ)); + + // Find intersection points for approximated camera differential rays + Ray xRay(Point3f(0, 0, 0) + minPosDifferentialX, + Vector3f(0, 0, 1) + minDirDifferentialX); + Float tx = -(Dot(nDownZ, Vector3f(xRay.o)) - d) / Dot(nDownZ, xRay.d); + Ray yRay(Point3f(0, 0, 0) + minPosDifferentialY, + Vector3f(0, 0, 1) + minDirDifferentialY); + Float ty = -(Dot(nDownZ, Vector3f(yRay.o)) - d) / Dot(nDownZ, yRay.d); + Point3f px = xRay(tx), py = yRay(ty); + + // Estimate $\dpdx$ and $\dpdy$ in tangent plane at intersection point Float sppScale = GetOptions().disablePixelJitter ? 1 : std::max(.125, 1 / std::sqrt((Float)samplesPerPixel)); - - Frame f = Frame::FromZ(si.n); - // ray plane: - // (0,0,0) + minPosDifferential + ((0,0,1) + minDirDifferantial)) * t = (x, - // x, dist) - Float tx = (dist - minPosDifferentialX.z) / (1 + minDirDifferentialX.z); - si.dpdx = sppScale * f.FromLocal(minPosDifferentialX + tx * minDirDifferentialX); - Float ty = (dist - minPosDifferentialY.z) / (1 + minDirDifferentialY.z); - si.dpdy = sppScale * f.FromLocal(minPosDifferentialY + ty * minDirDifferentialY); + si.dpdx = + sppScale * RenderFromCamera(DownZFromCamera.ApplyInverse(px - pDownZ), si.time); + si.dpdy = + sppScale * RenderFromCamera(DownZFromCamera.ApplyInverse(py - pDownZ), si.time); } void CameraBase::FindMinimumDifferentials(CameraHandle camera) { diff --git a/src/pbrt/cameras.h b/src/pbrt/cameras.h index a1e4e02f446e04d7cf39e3bd19e9de466d5917f3..16ad999fad2c95b41b6f949c445d506643c6bab7 100644 --- a/src/pbrt/cameras.h +++ b/src/pbrt/cameras.h @@ -61,6 +61,11 @@ class CameraTransform { return renderFromCamera(v, time); } + PBRT_CPU_GPU + Normal3f RenderFromCamera(const Normal3f &n, Float time) const { + return renderFromCamera(n, time); + } + PBRT_CPU_GPU Ray RenderFromCamera(const Ray &r) const { return renderFromCamera(r); } @@ -74,6 +79,11 @@ class CameraTransform { return renderFromCamera.ApplyInverse(v, time); } + PBRT_CPU_GPU + Normal3f CameraFromRender(const Normal3f &v, Float time) const { + return renderFromCamera.ApplyInverse(v, time); + } + std::string ToString() const; private: @@ -171,6 +181,11 @@ class CameraBase { return cameraTransform.RenderFromCamera(v, time); } + PBRT_CPU_GPU + Normal3f RenderFromCamera(const Normal3f &v, Float time) const { + return cameraTransform.RenderFromCamera(v, time); + } + PBRT_CPU_GPU Point3f RenderFromCamera(const Point3f &p, Float time) const { return cameraTransform.RenderFromCamera(p, time); @@ -181,6 +196,11 @@ class CameraBase { return cameraTransform.CameraFromRender(v, time); } + PBRT_CPU_GPU + Normal3f CameraFromRender(const Normal3f &v, Float time) const { + return cameraTransform.CameraFromRender(v, time); + } + PBRT_CPU_GPU Point3f CameraFromRender(const Point3f &p, Float time) const { return cameraTransform.CameraFromRender(p, time); diff --git a/src/pbrt/interaction.cpp b/src/pbrt/interaction.cpp index d3242c076a7dc56e508e1d340260781dc2b8f720..8e69dc6c059bf2386c8a28a030b366565db2a8f9 100644 --- a/src/pbrt/interaction.cpp +++ b/src/pbrt/interaction.cpp @@ -80,9 +80,17 @@ void SurfaceInteraction::ComputeDifferentials(const RayDifferential &ray, dvdy = std::isfinite(dvdy) ? Clamp(dvdy, -1e8f, 1e8f) : 0.f; } +void SurfaceInteraction::SkipIntersection(RayDifferential *ray, Float t) const { + *((Ray *)ray) = SpawnRay(ray->d); + if (ray->hasDifferentials) { + ray->rxOrigin = ray->rxOrigin + t * ray->rxDirection; + ray->ryOrigin = ray->ryOrigin + t * ray->ryDirection; + } +} + RayDifferential SurfaceInteraction::SpawnRay(const RayDifferential &rayi, - const BSDF &bsdf, const Vector3f &wi, - int /*BxDFFlags*/ flags) const { + const BSDF &bsdf, Vector3f wi, + int flags) const { RayDifferential rd(SpawnRay(wi)); if (rayi.hasDifferentials) { // Compute ray differentials for specular reflection or transmission @@ -92,52 +100,47 @@ RayDifferential SurfaceInteraction::SpawnRay(const RayDifferential &rayi, Normal3f dndy = shading.dndu * dudy + shading.dndv * dvdy; Vector3f dwodx = -rayi.rxDirection - wo, dwody = -rayi.ryDirection - wo; - if (flags == (BxDFFlags::Reflection | BxDFFlags::Specular)) { + if (flags == BxDFFlags::SpecularReflection) { // Initialize origins of specular differential rays rd.hasDifferentials = true; rd.rxOrigin = p() + dpdx; rd.ryOrigin = p() + dpdy; // Compute differential reflected directions - Float dDNdx = Dot(dwodx, ns) + Dot(wo, dndx); - Float dDNdy = Dot(dwody, ns) + Dot(wo, dndy); - rd.rxDirection = wi - dwodx + 2.f * Vector3f(Dot(wo, ns) * dndx + dDNdx * ns); - rd.ryDirection = wi - dwody + 2.f * Vector3f(Dot(wo, ns) * dndy + dDNdy * ns); - - } else if (flags == (BxDFFlags::Transmission | BxDFFlags::Specular)) { + Float dwoDotNdx = Dot(dwodx, ns) + Dot(wo, dndx); + Float dwoDotNdy = Dot(dwody, ns) + Dot(wo, dndy); + rd.rxDirection = + wi - dwodx + 2 * Vector3f(Dot(wo, ns) * dndx + dwoDotNdx * ns); + rd.ryDirection = + wi - dwody + 2 * Vector3f(Dot(wo, ns) * dndy + dwoDotNdy * ns); + + } else if (flags == BxDFFlags::SpecularTransmission) { // Initialize origins of specular differential rays rd.hasDifferentials = true; rd.rxOrigin = p() + dpdx; rd.ryOrigin = p() + dpdy; // Compute differential transmitted directions - // NOTE: eta coming in is now 1/eta from the derivation below, so - // there's a 1/ here now... + // Find _eta_ and oriented surface normal for transmission Float eta = 1 / bsdf.eta; if (Dot(wo, ns) < 0) { ns = -ns; dndx = -dndx; dndy = -dndy; } - Float dDNdx = Dot(dwodx, ns) + Dot(wo, dndx); - Float dDNdy = Dot(dwody, ns) + Dot(wo, dndy); + // Compute partial derivatives of $\mu$ + Float dwoDotNdx = Dot(dwodx, ns) + Dot(wo, dndx); + Float dwoDotNdy = Dot(dwody, ns) + Dot(wo, dndy); Float mu = eta * Dot(wo, ns) - AbsDot(wi, ns); - Float dmudx = (eta - (eta * eta * Dot(wo, ns)) / AbsDot(wi, ns)) * dDNdx; - Float dmudy = (eta - (eta * eta * Dot(wo, ns)) / AbsDot(wi, ns)) * dDNdy; + Float dmudx = (eta - (eta * eta * Dot(wo, ns)) / AbsDot(wi, ns)) * dwoDotNdx; + Float dmudy = (eta - (eta * eta * Dot(wo, ns)) / AbsDot(wi, ns)) * dwoDotNdy; rd.rxDirection = wi - eta * dwodx + Vector3f(mu * dndx + dmudx * ns); rd.ryDirection = wi - eta * dwody + Vector3f(mu * dndy + dmudy * ns); } } // Squash potentially troublesome differentials - // After many specuar bounces (e.g. the Transparent Machines scenes), - // differentials can drift off to have large magnitudes, which ends up - // leaving a trail of Infs and NaNs in their wake. We'll disable the - // differentials when this seems to be happening. - // - // TODO: this is unsatisfying and would be nice to address in a more - // principled way. if (LengthSquared(rd.rxDirection) > 1e16f || LengthSquared(rd.ryDirection) > 1e16f || LengthSquared(Vector3f(rd.rxOrigin)) > 1e16f || LengthSquared(Vector3f(rd.ryOrigin)) > 1e16f) @@ -146,14 +149,6 @@ RayDifferential SurfaceInteraction::SpawnRay(const RayDifferential &rayi, return rd; } -void SurfaceInteraction::SkipIntersection(RayDifferential *ray, Float t) const { - *((Ray *)ray) = SpawnRay(ray->d); - if (ray->hasDifferentials) { - ray->rxOrigin = ray->rxOrigin + t * ray->rxDirection; - ray->ryOrigin = ray->ryOrigin + t * ray->ryDirection; - } -} - BSDF SurfaceInteraction::GetBSDF(const RayDifferential &ray, SampledWavelengths &lambda, CameraHandle camera, ScratchBuffer &scratchBuffer, SamplerHandle sampler) { diff --git a/src/pbrt/interaction.h b/src/pbrt/interaction.h index b76b08e1fb7e8854d1b9125078aba9f287b8a664..43a53076e207972b69d18e0777db5e5277fc7557 100644 --- a/src/pbrt/interaction.h +++ b/src/pbrt/interaction.h @@ -248,13 +248,13 @@ class SurfaceInteraction : public Interaction { void ComputeDifferentials(const RayDifferential &r, CameraHandle camera, int samplesPerPixel); - using Interaction::SpawnRay; PBRT_CPU_GPU - RayDifferential SpawnRay(const RayDifferential &rayi, const BSDF &bsdf, - const Vector3f &wi, int /*BxDFFlags*/ flags) const; + void SkipIntersection(RayDifferential *ray, Float t) const; + using Interaction::SpawnRay; PBRT_CPU_GPU - void SkipIntersection(RayDifferential *ray, Float t) const; + RayDifferential SpawnRay(const RayDifferential &rayi, const BSDF &bsdf, Vector3f wi, + int /*BxDFFlags*/ flags) const; PBRT_CPU_GPU BSDF GetBSDF(const RayDifferential &ray, SampledWavelengths &lambda, diff --git a/src/pbrt/materials.h b/src/pbrt/materials.h index c03ff56b755d0faed0669023e27c505012dbdde6..52da864d1818d229134239272e39f0be55621651 100644 --- a/src/pbrt/materials.h +++ b/src/pbrt/materials.h @@ -25,6 +25,7 @@ namespace pbrt { // MaterialEvalContext Definition struct MaterialEvalContext : public TextureEvalContext { + // MaterialEvalContext Public Methods MaterialEvalContext() = default; PBRT_CPU_GPU MaterialEvalContext(const SurfaceInteraction &si) diff --git a/src/pbrt/paramdict.cpp b/src/pbrt/paramdict.cpp index bf123789e892d3c1afbb704ee2058f3acfb5dfe6..145dc22b3671047325c10d8f7aeb821fb41da583 100644 --- a/src/pbrt/paramdict.cpp +++ b/src/pbrt/paramdict.cpp @@ -835,13 +835,14 @@ SpectrumTextureHandle TextureParameterDictionary::GetSpectrumTextureOrNull( ErrorExit(&p->loc, "Negative value provided for \"rgb\" parameter \"%s\".", p->name); + SpectrumHandle s; if (spectrumType == SpectrumType::General) - return alloc.new_object(*dict->ColorSpace(), rgb); + s = alloc.new_object(*dict->ColorSpace(), rgb); else { CHECK(spectrumType == SpectrumType::Reflectance); - return alloc.new_object( - *dict->ColorSpace(), rgb); + s = alloc.new_object(*dict->ColorSpace(), rgb); } + return alloc.new_object(s); } else if (p->type == "spectrum" || p->type == "blackbody") { SpectrumHandle s = GetOneSpectrum(name, nullptr, spectrumType, alloc); CHECK(s != nullptr); diff --git a/src/pbrt/textures.cpp b/src/pbrt/textures.cpp index 869dfe8893e4400cb2a915d298bd6454c0eddb7e..06636a0dcdc89c8c270fba24fca73505426de496 100644 --- a/src/pbrt/textures.cpp +++ b/src/pbrt/textures.cpp @@ -100,14 +100,6 @@ FloatConstantTexture *FloatConstantTexture::Create( return alloc.new_object(parameters.GetOneFloat("value", 1.f)); } -std::string RGBConstantTexture::ToString() const { - return StringPrintf("[ RGBConstantTexture value: %s ]", value); -} - -std::string RGBReflectanceConstantTexture::ToString() const { - return StringPrintf("[ RGBReflectanceConstantTexture value: %s ]", value); -} - std::string SpectrumConstantTexture::ToString() const { return StringPrintf("[ SpectrumConstantTexture value: %s ]", value); } diff --git a/src/pbrt/textures.h b/src/pbrt/textures.h index d486e9dfe5ee9baa1ca8d6126edd06abdd266706..f6668d235bcf487d0fc785df4f80363d956d75d1 100644 --- a/src/pbrt/textures.h +++ b/src/pbrt/textures.h @@ -27,6 +27,7 @@ namespace pbrt { // TextureEvalContext Definition struct TextureEvalContext { + // TextureEvalContext Public Methods TextureEvalContext() = default; PBRT_CPU_GPU TextureEvalContext(const SurfaceInteraction &si) @@ -93,12 +94,12 @@ class SphericalMapping2D { PBRT_CPU_GPU Point2f Map(TextureEvalContext ctx, Vector2f *dstdx, Vector2f *dstdy) const { - Point2f st = sphere(ctx.p); + Point2f st = Sphere(ctx.p); // Compute texture coordinate differentials for sphere $(u,v)$ mapping - const Float delta = .1f; - Point2f stDeltaX = sphere(ctx.p + delta * ctx.dpdx); + Float delta = .1f; + Point2f stDeltaX = Sphere(ctx.p + delta * ctx.dpdx); *dstdx = (stDeltaX - st) / delta; - Point2f stDeltaY = sphere(ctx.p + delta * ctx.dpdy); + Point2f stDeltaY = Sphere(ctx.p + delta * ctx.dpdy); *dstdy = (stDeltaY - st) / delta; // Handle sphere mapping discontinuity for coordinate differentials @@ -117,7 +118,7 @@ class SphericalMapping2D { private: // SphericalMapping2D Private Methods PBRT_CPU_GPU - Point2f sphere(const Point3f &p) const { + Point2f Sphere(const Point3f &p) const { Vector3f vec = Normalize(textureFromRender(p) - Point3f(0, 0, 0)); Float theta = SphericalTheta(vec), phi = SphericalPhi(vec); return {theta * InvPi, phi * Inv2Pi}; @@ -137,16 +138,16 @@ class CylindricalMapping2D { PBRT_CPU_GPU Point2f Map(TextureEvalContext ctx, Vector2f *dstdx, Vector2f *dstdy) const { - Point2f st = cylinder(ctx.p); + Point2f st = Cylinder(ctx.p); // Compute texture coordinate differentials for cylinder $(u,v)$ mapping const Float delta = .01f; - Point2f stDeltaX = cylinder(ctx.p + delta * ctx.dpdx); + Point2f stDeltaX = Cylinder(ctx.p + delta * ctx.dpdx); *dstdx = (stDeltaX - st) / delta; if ((*dstdx)[1] > .5) (*dstdx)[1] = 1.f - (*dstdx)[1]; else if ((*dstdx)[1] < -.5f) (*dstdx)[1] = -((*dstdx)[1] + 1); - Point2f stDeltaY = cylinder(ctx.p + delta * ctx.dpdy); + Point2f stDeltaY = Cylinder(ctx.p + delta * ctx.dpdy); *dstdy = (stDeltaY - st) / delta; if ((*dstdy)[1] > .5) (*dstdy)[1] = 1.f - (*dstdy)[1]; @@ -159,7 +160,7 @@ class CylindricalMapping2D { private: // CylindricalMapping2D Private Methods PBRT_CPU_GPU - Point2f cylinder(const Point3f &p) const { + Point2f Cylinder(const Point3f &p) const { Vector3f vec = Normalize(textureFromRender(p) - Point3f(0, 0, 0)); return Point2f((Pi + std::atan2(vec.y, vec.x)) * Inv2Pi, vec.z); } @@ -172,7 +173,7 @@ class CylindricalMapping2D { class PlanarMapping2D { public: // PlanarMapping2D Public Methods - PlanarMapping2D(const Vector3f &vs, const Vector3f &vt, Float ds = 0, Float dt = 0) + PlanarMapping2D(Vector3f vs, Vector3f vt, Float ds, Float dt) : vs(vs), vt(vt), ds(ds), dt(dt) {} PBRT_CPU_GPU @@ -263,6 +264,7 @@ inline Point3f TextureMapping3DHandle::Map(TextureEvalContext ctx, Vector3f *dpd // FloatConstantTexture Definition class FloatConstantTexture { public: + // FloatConstantTexture Public Methods FloatConstantTexture(Float value) : value(value) {} PBRT_CPU_GPU @@ -278,42 +280,10 @@ class FloatConstantTexture { Float value; }; -// RGBConstantTexture Definition -class RGBConstantTexture { - public: - RGBConstantTexture(const RGBColorSpace &cs, const RGB &rgb) : value(cs, rgb) {} - - PBRT_CPU_GPU - SampledSpectrum Evaluate(TextureEvalContext ctx, SampledWavelengths lambda) const { - return value.Sample(lambda); - } - - std::string ToString() const; - - private: - RGBSpectrum value; -}; - -// RGBReflectanceConstantTexture Definition -class RGBReflectanceConstantTexture { - public: - RGBReflectanceConstantTexture(const RGBColorSpace &cs, const RGB &rgb) - : value(cs, rgb) {} - - PBRT_CPU_GPU - SampledSpectrum Evaluate(TextureEvalContext ctx, SampledWavelengths lambda) const { - return value.Sample(lambda); - } - - std::string ToString() const; - - private: - RGBReflectanceSpectrum value; -}; - // SpectrumConstantTexture Definition class SpectrumConstantTexture { public: + // SpectrumConstantTexture Public Methods SpectrumConstantTexture(SpectrumHandle value) : value(value) { DCHECK(value); } PBRT_CPU_GPU @@ -793,7 +763,7 @@ class MarbleTexture { // FloatMixTexture Definition class FloatMixTexture { public: - // MixTexture Public Methods + // FloatMixTexture Public Methods FloatMixTexture(FloatTextureHandle tex1, FloatTextureHandle tex2, FloatTextureHandle amount) : tex1(tex1), tex2(tex2), amount(amount) {} @@ -891,6 +861,7 @@ class SpectrumPtexTexture : public PtexTextureBase { // FloatScaledTexture Definition class FloatScaledTexture { public: + // FloatScaledTexture Public Methods FloatScaledTexture(FloatTextureHandle tex, FloatTextureHandle scale) : tex(tex), scale(scale) {} @@ -994,6 +965,7 @@ inline SampledSpectrum SpectrumTextureHandle::Evaluate(TextureEvalContext ctx, return Dispatch(eval); } +// UniversalTextureEvaluator Definition class UniversalTextureEvaluator { public: PBRT_CPU_GPU @@ -1019,9 +991,8 @@ class BasicTextureEvaluator { return false; } for (auto s : stex) - if (s && (!s.Is() && !s.Is() && - !s.Is() && - !s.Is())) { + if (s && + (!s.Is() && !s.Is())) { return false; } return true; @@ -1042,11 +1013,6 @@ class BasicTextureEvaluator { SampledWavelengths lambda) { if (SpectrumConstantTexture *sc = tex.CastOrNullptr()) return sc->Evaluate(ctx, lambda); - else if (RGBConstantTexture *rgbc = tex.CastOrNullptr()) - return rgbc->Evaluate(ctx, lambda); - else if (RGBReflectanceConstantTexture *rgbc = - tex.CastOrNullptr()) - return rgbc->Evaluate(ctx, lambda); else if (GPUSpectrumImageTexture *sg = tex.CastOrNullptr()) return sg->Evaluate(ctx, lambda);