跳过正文

pbrt-v4 Ep. IX: 反射模型

·25365 字·51 分钟
目录

pbrt将反射分为以下四类: 漫反射, 光滑镜面反射, 完美镜面反射, 回溯反射. 反射分布方程可以被分为各向同性与各向异性的, 若将物体旋转时在各个角度上具有相同的反射结果即位各向同性, 反之则为各向异性.

BSDF表示
#

pbrt中BxDF接口代表特定种类表面散射的实现, BSDF则是围绕BxDF指针做一层封装并提供额外功能.

几何设置与约定
#

pbrt中法线计算发生在由表面的切线, 副切线与法线组成的坐标系中, 分别与x,y,zx,y,z轴对齐. pbrt中光线入射方向与观察方向都会被归一化并方向朝外, 法线也始终朝外. 着色所用的坐标系很可能与相交所用的不同, 这便于实现法线映射等效果.

BxDF接口
#

单独的BRDF与BTDF方法都定义在BxDF接口中.

class BxDF
    : public TaggedPointer<DiffuseTransmissionBxDF, DiffuseBxDF, CoatedDiffuseBxDF,
                           CoatedConductorBxDF, DielectricBxDF, ThinDielectricBxDF,
                           HairBxDF, MeasuredBxDF, ConductorBxDF, NormalizedFresnelBxDF> {
  public:
    // BxDF Interface
    PBRT_CPU_GPU inline BxDFFlags Flags() const;

    using TaggedPointer::TaggedPointer;

    std::string ToString() const;

    PBRT_CPU_GPU inline SampledSpectrum f(Vector3f wo, Vector3f wi,
                                          TransportMode mode) const;

    PBRT_CPU_GPU inline pstd::optional<BSDFSample> Sample_f(
        Vector3f wo, Float uc, Point2f u, TransportMode mode = TransportMode::Radiance,
        BxDFReflTransFlags sampleFlags = BxDFReflTransFlags::All) const;

    PBRT_CPU_GPU inline Float PDF(
        Vector3f wo, Vector3f wi, TransportMode mode,
        BxDFReflTransFlags sampleFlags = BxDFReflTransFlags::All) const;

    PBRT_CPU_GPU
    SampledSpectrum rho(Vector3f wo, pstd::span<const Float> uc,
                        pstd::span<const Point2f> u2) const;
    SampledSpectrum rho(pstd::span<const Point2f> u1, pstd::span<const Float> uc2,
                        pstd::span<const Point2f> u2) const;

    PBRT_CPU_GPU inline void Regularize();
};

Flags方法用于返回上文所述的材质类型以及区分反射与透射, 部分光线传播算法会通过该返回值决定行为.

enum BxDFFlags {
    Unset = 0,
    Reflection = 1 << 0,
    Transmission = 1 << 1,
    Diffuse = 1 << 2,
    Glossy = 1 << 3,
    Specular = 1 << 4,
    // Composite _BxDFFlags_ definitions
    DiffuseReflection = Diffuse | Reflection,
    DiffuseTransmission = Diffuse | Transmission,
    GlossyReflection = Glossy | Reflection,
    GlossyTransmission = Glossy | Transmission,
    SpecularReflection = Specular | Reflection,
    SpecularTransmission = Specular | Transmission,
    All = Diffuse | Glossy | Specular | Reflection | Transmission

};

BxDF的关键方法是f, 它根据方向返回BxDF的值, 方向需要位于前文所述的材质的本地空间中. BxDF接口认为不同波长的光是被解耦的, 某个波长上的能量不会被反射到不同的波长上, 因此f的返回值通过SampledSpectrum来表达. 荧光材质会在不同的波长间重新分布能量, 需要返回n×nn \times n的矩阵来表示nn个光谱样本之间的转移. BxDF的构造函数以及各种方法都没有SampledSpectrum中具体某个波长的信息, 这是不需要的. TransportMode用于表示出射方向是对着相机还是对着光源, 不对称散射会用到这一特性.

PBRT_CPU_GPU inline SampledSpectrum BxDF::f(Vector3f wo, Vector3f wi, TransportMode mode) const {
    auto f = [&](auto ptr) -> SampledSpectrum { return ptr->f(wo, wi, mode); };
    return Dispatch(f);
}

BxDF还需要提供用于重要性抽样的方法, Sample_f用于实现这一任务. 由于光线路径是逆向构造的, 因此这里出射方向作为参数, 采样得到的入射方向. 参数中的ucu用于实现一维与二维的采样, 通常uc用于选择反射或透射, u用于选择方向.

PBRT_CPU_GPU inline pstd::optional<BSDFSample> BxDF::Sample_f(Vector3f wo, Float uc, Point2f u,
                                                 TransportMode mode,
                                                 BxDFReflTransFlags sampleFlags) const {
    auto sample_f = [&](auto ptr) -> pstd::optional<BSDFSample> {
        return ptr->Sample_f(wo, uc, u, mode, sampleFlags);
    };
    return Dispatch(sample_f);
}

用户可以通过sampleFlags参数限制采样结果为透射或反射, 像在不透明表面采样透射样本的不合法采样会导致采样失效.

enum class BxDFReflTransFlags {
    Unset = 0,
    Reflection = 1 << 0,
    Transmission = 1 << 1,
    All = Reflection | Transmission
};

若采样成功, BSDF的值, 入射方向, 分布密度以及对应的flags会被返回, 这里返回的wi位于本地空间中, 在BSDF中会转到渲染空间.

struct BSDFSample {
    // BSDFSample Public Methods
    BSDFSample() = default;
    PBRT_CPU_GPU
    BSDFSample(SampledSpectrum f, Vector3f wi, Float pdf, BxDFFlags flags, Float eta = 1,
               bool pdfIsProportional = false)
        : f(f),
          wi(wi),
          pdf(pdf),
          flags(flags),
          eta(eta),
          pdfIsProportional(pdfIsProportional) {}

    PBRT_CPU_GPU
    bool IsReflection() const { return pbrt::IsReflective(flags); }
    PBRT_CPU_GPU
    bool IsTransmission() const { return pbrt::IsTransmissive(flags); }
    PBRT_CPU_GPU
    bool IsDiffuse() const { return pbrt::IsDiffuse(flags); }
    PBRT_CPU_GPU
    bool IsGlossy() const { return pbrt::IsGlossy(flags); }
    PBRT_CPU_GPU
    bool IsSpecular() const { return pbrt::IsSpecular(flags); }

    std::string ToString() const;
    SampledSpectrum f;
    Vector3f wi;
    Float pdf = 0;
    BxDFFlags flags;
    Float eta = 1;
    bool pdfIsProportional = false;
};

半球反射
#

rho方法的两种重载分别用于计算第四章所介绍的半球-方向反射量与半球-半球反射量, 样本数量由调用者决定.

PBRT_CPU_GPU SampledSpectrum BxDF::rho(Vector3f wo, pstd::span<const Float> uc,
                          pstd::span<const Point2f> u2) const {
    if (wo.z == 0)
        return {};
    SampledSpectrum r(0.);
    DCHECK_EQ(uc.size(), u2.size());
    for (size_t i = 0; i < uc.size(); ++i) {
        // Compute estimate of $\rho_\roman{hd}$
        pstd::optional<BSDFSample> bs = Sample_f(wo, uc[i], u2[i]);
        if (bs && bs->pdf > 0)
            r += bs->f * AbsCosTheta(bs->wi) / bs->pdf;
    }
    return r / uc.size();
}

SampledSpectrum BxDF::rho(pstd::span<const Point2f> u1, pstd::span<const Float> uc,
                          pstd::span<const Point2f> u2) const {
    DCHECK_EQ(uc.size(), u1.size());
    DCHECK_EQ(u1.size(), u2.size());
    SampledSpectrum r(0.f);
    for (size_t i = 0; i < uc.size(); ++i) {
        // Compute estimate of $\rho_\roman{hh}$
        Vector3f wo = SampleUniformHemisphere(u1[i]);
        if (wo.z == 0)
            continue;
        Float pdfo = UniformHemispherePDF();
        pstd::optional<BSDFSample> bs = Sample_f(wo, uc[i], u2[i]);
        if (bs && bs->pdf > 0)
            r += bs->f * AbsCosTheta(bs->wi) * AbsCosTheta(wo) / (pdfo * bs->pdf);
    }
    return r / (Pi * uc.size());
}

BSDF中的Delta分布
#

Delta分布主要用于完美镜面反射, 但是对于Sample_fPDF方法, 返回Delta函数对应的无穷大密度在c++中是无法得到正确的渲染结果的. 对于Sample_f方法, 将Delta函数从PDF与BSDF分离, 可以发现Delta函数会被抵消, 由于PDF与Delta函数一致, 因此PDF设置为1即可. 对于PDF方法, 它的返回值为0, 因为恰好位于Delta函数对应的反射方向的概率过小.

fr(p,ωo,ωi)p(ωi)=δ(ωωi)frrem(p,ωo,ωi)δ(ωωi)prem(ωi)=frrem(p,ωo,ωi)prem(ωi) \begin{equation} \frac{f_r(p, \omega_o, \omega_i)}{p(\omega_i)} = \frac{\delta(\omega' - \omega_i)f_r^{\text{rem}}(p, \omega_o, \omega_i)}{\delta(\omega' - \omega_i)p^{\text{rem}(\omega_i)}} = \frac{f_r^{\text{rem}}(p, \omega_o, \omega_i)}{p^{\text{rem}(\omega_i)}} \end{equation}

BSDF类
#

BSDF主要用于处理从材质本地空间到渲染空间的转换. BSDF的构造函数会传入几何法线, 着色法线以及切线, shadingFrame用于存储着色所用的坐标系以及处理与渲染空间之间的转换.

BSDF() = default;
PBRT_CPU_GPU
BSDF(Normal3f ns, Vector3f dpdus, BxDF bxdf)
    : bxdf(bxdf), shadingFrame(Frame::FromXZ(Normalize(dpdus), Vector3f(ns))) {}

BSDFf方法用于封装BxDF中的对应方法, 其中的模板版本用于在用户已知内部BxDF类型的情况下直接调用它的f方法, 这用于在GPU上避免pbrt中的动态方法分发.

PBRT_CPU_GPU
SampledSpectrum f(Vector3f woRender, Vector3f wiRender,
                    TransportMode mode = TransportMode::Radiance) const {
    Vector3f wi = RenderToLocal(wiRender), wo = RenderToLocal(woRender);
    if (wo.z == 0)
        return {};
    return bxdf.f(wo, wi, mode);
}

template <typename BxDF>
PBRT_CPU_GPU SampledSpectrum f(Vector3f woRender, Vector3f wiRender,
                                TransportMode mode = TransportMode::Radiance) const {
    Vector3f wi = RenderToLocal(wiRender), wo = RenderToLocal(woRender);
    if (wo.z == 0)
        return {};
    const BxDF *specificBxDF = bxdf.CastOrNullptr<BxDF>();
    return specificBxDF->f(wo, wi, mode);
}

BSDFSample_f会通过std::optional处理采样失效的情况.

PBRT_CPU_GPU
pstd::optional<BSDFSample> Sample_f(
    Vector3f woRender, Float u, Point2f u2,
    TransportMode mode = TransportMode::Radiance,
    BxDFReflTransFlags sampleFlags = BxDFReflTransFlags::All) const {
    Vector3f wo = RenderToLocal(woRender);
    if (wo.z == 0 || !(bxdf.Flags() & sampleFlags))
        return {};
    // Sample _bxdf_ and return _BSDFSample_
    pstd::optional<BSDFSample> bs = bxdf.Sample_f(wo, u, u2, mode, sampleFlags);
    if (bs)
        DCHECK_GE(bs->pdf, 0);
    if (!bs || !bs->f || bs->pdf == 0 || bs->wi.z == 0)
        return {};
    PBRT_DBG("For wo = (%f, %f, %f), ns %f %f %f sampled f = %f %f %f %f, pdf = %f, "
                "ratio[0] = %f wi = (%f, %f, %f)\n",
                wo.x, wo.y, wo.z, shadingFrame.z.x, shadingFrame.z.y, shadingFrame.z.z,
                bs->f[0], bs->f[1], bs->f[2], bs->f[3], bs->pdf,
                (bs->pdf > 0) ? (bs->f[0] / bs->pdf) : 0, bs->wi.x, bs->wi.y, bs->wi.z);
    bs->wi = LocalToRender(bs->wi);
    return bs;
}

漫反射
#

Lambertian反射模型是最简单的BRDF之一, 它表达了将入射光线均匀的反射到各个方向的完美漫反射. 大部分角度下Lambertian模型都可以很好的表达漫反射, 但是在与法线接近垂直的掠射角下镜面反射会导致明显的偏差.

Lambertian反射的表达式如下, 其中的π\pi来自于积分得到的反射值. 在实时渲染中, 材质的反照率通常会预先乘上π\pi, 这避免了耗时的除法操作.

ωfr(p,ωo,ωi)cosθdω=02π0π2Rπcosθsinθdθdϕ=R \begin{equation} \int_\omega f_r(p, \omega_o, \omega_i) \cos\theta \mathrm{d}\omega = \int_0^{2\pi}\int_0^{\frac{\pi}{2}} \frac{R}{\pi} \cos\theta \sin\theta \mathrm{d}\theta \mathrm{d}\phi = R \end{equation}

pbrt在采样Lambertian时会将cos\cos项考虑进pdf中, 这使得分布不再均匀, 但能通过重要性抽样获得更好的渲染结果.

// Sample cosine-weighted hemisphere to compute _wi_ and _pdf_
Vector3f wi = SampleCosineHemisphere(u);
if (wo.z < 0)
    wi.z *= -1;
Float pdf = CosineHemispherePDF(AbsCosTheta(wi));

圆盘采样
#

对极坐标r,θr,\theta分别做重要性抽样会导致样本集中在圆盘中央, 因为虽然距离圆心距离的分布是均匀的, 由于不同半径下周长不同, 外侧点的分布会减少.

为了保证样本点在面积上均匀分布, 需要满足p(x,y)=1πp(x,y)=\frac{1}{\pi}, 使用Jacobi转为极坐标后可得p(r,θ)=rπp(r,\theta)=\frac{r}{\pi}. 此时可以计算出如下PDF.

p(r)=02πp(r,θ)dθ=2rp(θr)=p(r,θ)p(r)=12π \begin{equation} \begin{aligned} p(r)&=\int_0^{2\pi}p(r,\theta)\mathrm{d}\theta=2r\\ p(\theta|r)&=\frac{p(r,\theta)}{p(r)}=\frac{1}{2\pi} \end{aligned} \end{equation}

根据重要性抽样得到的结果如下, 此时根据Jacobian可得drdθ=πxdxdydrd\theta=\frac{\pi}{\sqrt{x}}dxdy, 均匀采样结果映射为圆盘采样结果时所占的面积并不均匀, 越靠近圆盘边缘所占面积越狭窄.

r=ϵ1θ=2πϵ2 \begin{equation} \begin{aligned} r&=\sqrt{\epsilon_1}\\ \theta&=2\pi\epsilon_2 \end{aligned} \end{equation}

Shirley-Chiu方法可以解决这一问题, 根据Cartesian轴及y=x,y=xy=x,y=-x[1,1][-1,1]空间分为八个象限, 每个象限根据max(x,y\max(x,y)选出的轴是一致的, 长轴选取aa点, 短轴选取bb点, 需保证该ab2\frac{ab}{2}面积的区域内的采样点在Cartesian及极坐标下所占面积成常数关系. 由于圆弧面积为θr22\frac{\theta r^2}{2}, 如下表达式可满足上述条件, 在极坐标中占的面积为πab8\frac{\pi ab}{8}, 看图片会更直观.

r={xx>yyxyθ={π4yxx>yπ2xyxy \begin{equation} \begin{aligned} r&= \begin{cases} x & |x|>|y|\\ y & |x| \le |y| \end{cases}\\ \theta&= \begin{cases} \frac{\pi}{4}\frac{y}{x} & |x| > |y|\\ \frac{\pi}{2} - \frac{x}{y} & |x| \le |y| \end{cases} \end{aligned} \end{equation}

此时Jacobian行列式满足如下关系, 因此p(r,θ)=J1p(u,v)=J114=rπp(r,\theta)=|J|^{-1}p(u,v)=|J|^{-1}\frac{1}{4}=\frac{r}{\pi}.

J={π4x=π4rx>yπ4y=π4rxy \begin{equation} \begin{aligned} |J|&= \begin{cases} \frac{\pi}{4x}=\frac{\pi}{4r} & |x|>|y|\\ \frac{\pi}{4y}=\frac{\pi}{4r} & |x|\le|y| \end{cases} \end{aligned} \end{equation}

余弦加权半球采样
#

渲染方程中有余弦项, 将它与BSDF一起做重要性抽样可以有效的考虑余弦的影响, 例如减小与法线夹角较大的光线被采样到的概率. 令p(ω)=ccosθp(\omega)=c\cos\theta, 此时可以得到如下关系.

Θp(ω)dω=102π0π2ccosθsinθdθdϕ=1 c=1πp(θ,ϕ)=1πcosθsinθ \begin{equation} \begin{aligned} &\int_\Theta p(\omega)\mathrm{d}\omega=1\\ &\int_0^{2\pi}\int_0^{\frac{\pi}{2}}c\cos\theta\sin\theta \mathrm{d}\theta \mathrm{d}\phi=1\\\ &c=\frac{1}{\pi}\\ &p(\theta,\phi)=\frac{1}{\pi}\cos\theta\sin\theta \end{aligned} \end{equation}

Malley方法通过将均匀圆盘采样的结果投影到半球上实现重要性抽样. 由于此时r=sinθr=\sin\theta,将r,ϕr,\phi转为θ,ϕ\theta,\phi的Jacobian如下, 由此可得p(θ,ϕ)=p(r,ϕ)cosθ=sinθcosθπp(\theta,\phi)=p(r,\phi)\cos\theta=\frac{\sin\theta\cos\theta}{\pi}, 满足重要性抽样的要求.

J=rθrϕϕθϕϕ=cosθ001=cosθ \begin{equation} \begin{aligned} |J|=\begin{vmatrix} \frac{\partial r}{\partial \theta} & \frac{\partial r}{\partial \phi}\\ \frac{\partial \phi}{\partial \theta} & \frac{\partial \phi}{\partial \phi} \end{vmatrix} =\begin{vmatrix} \cos\theta & 0\\ 0 & 1 \end{vmatrix}=\cos\theta \end{aligned} \end{equation}

镜面反射与透射
#

镜面反射只会将光线反射到某个方向集合中, 本节主要关注完美镜面反射, 微表面理论对反射结果的影响会在后面讨论.

物理原理
#

pbrt主要关注几何光学, 在波长远小于物体尺寸时这是可行的, 但对光的本质的探究也是必要的. 根据电磁学的定义光是电磁场的振荡, pbrt只关注其中电场的部分即电子的运动, 当光与表面接触时会刺激表面上的电子使其剧烈振荡, 移动的电子会导致电场中振荡的叠加.

依据电磁学理论, 物质可以分为绝缘体, 导体与半导体. 绝缘体中电子不会脱离原子; 导体中电子可以自由移动, 但移动过程中会有能量衰减, 通常完全吸收会发生在距离表面小于0.1微米处; 半导体兼顾二者的特性, 例如硅在可见光内具有金属特性, 在红外光中则具有透明特性.

折射率
#

由光所激发的电子产生的振荡通常会比原本的振荡的速度要小, 速度减小的程度被称为折射率(index of refraction, IOR), 它通过真空光速与当前材质中的光速的比值来定义, 通常在1.0~2.5之间, 同时光的波长也会影响IOR. IOR的突变会导致反射率的增加, IOR的变化是我们能观察到物体的原因.

镜面反射法则
#

令入射光线方向为ωi\omega_i(如上文所述, 方向是朝外的, 并非光线的传播方向), 完美反射的方向如下.

ωr=ωi+2(nωi)n \begin{equation} \omega_r = -\omega_i + 2(\mathbf{n} \cdot \omega_i)\mathbf{n} \end{equation}

Snell定律
#

Snell定律描述了入射光线与折射光线在方向上的关系, 这可以通过Fermat原理推导得到, 即光的传播路径是耗时最小的路径, 通过求极值即可证明. 从Snell定律可以看出折射方向取决于IOR的比值即η=ηiηt\eta=\frac{\eta_i}{\eta_t}.

ηisinθi=ηtsinθtϕt=ϕi+π \begin{equation} \begin{aligned} \eta_i \sin\theta_i &= \eta_t \sin\theta_t\\ \phi_t &= \phi_i + \pi \end{aligned} \end{equation}

经过不同介质后, 由于光的不同波长的部分具有不同的IOR, 这导致传播方向不同, 这被称为散射, 通常会表现为经过介质后产生彩虹状的光锥.

利用Snell定律可以按如下方式表示折射光线. 当光线从物体内部发出时, 由于法线朝外, ωin\omega_i \cdot \mathbf{n}小于0, 需要对代码做适当调整.

ωt=ωiη+(cosθiηcosθt)n \begin{equation} \omega_t = \omega_i\eta + (\cos\theta_i\eta - \cos\theta_t) \mathbf{n} \end{equation}

当光线穿过光学密度更小(折射后的介质的IOR较小)时, 当入射天顶角超过θc=sin1(η1)\theta_c = \sin^{-1}(\eta^{-1})时折射天顶角会超过9090^{\circ}, 此时光线会完全反射.

Fresnel方程
#

Fresnel方程描述了光线折射与反射的量, 它是Maxwell方程在光滑平面上的解.

将光线分解为相对于表面的垂直与水平偏振, 它们因反射而产生的振幅的变化是不同的. 若θt>π2\theta_t>\frac{\pi}{2}可以认为是完全反射, Fresnel返回11. 可以看出若入射出射方向交换, Fresnel值是不变的.

r=ErEi=ηtcosθiηicosθtηtcosθi+ηicosθt=cosθiηcosθtcosθi+ηcosθtr=ErEi=ηicosθiηtcosθtηicosθi+ηtcosθt=ηcosθicosθtηcosθi+cosθt \begin{equation} \begin{aligned} r_{||} &= \frac{E_r^{||}}{E_i^{||}} &= \frac{\eta_t \cos\theta_i - \eta_i \cos\theta_t}{\eta_t \cos\theta_i + \eta_i \cos\theta_t} &= \frac{\cos\theta_i - \eta \cos\theta_t}{\cos\theta_i + \eta \cos\theta_t}\\ r_{\perp} &= \frac{E_r^{\perp}}{E_i^{\perp}} &= \frac{\eta_i \cos\theta_i - \eta_t \cos\theta_t}{\eta_i \cos\theta_i + \eta_t \cos\theta_t} &= \frac{\eta \cos\theta_i - \cos\theta_t}{\eta \cos\theta_i + \cos\theta_t} \end{aligned} \end{equation}

电磁学关注的是反射波的振幅与相位, 而pbrt的几何光学中更关注光线所携带的功率, 这可以通过振幅的平方来表示. 若入射光是无偏振的即含有等量的水平与垂直偏振, 此时反射功率为水平与垂直反射功率的平均值, 即位Fresnel反射率.

Fr=12(r2+r2) \begin{equation} F_r = \frac{1}{2}(r_{||}^2 + r_{\perp}^2) \end{equation}

实时渲染中通常使用Schlick近似.

Fr=Fr0+(1Fr0)(1cosθi)5Fr0=(ηiηtηi+ηt)2 \begin{equation} \begin{aligned} F_r &= F_{r_0}+(1-F_{r_0})(1-\cos\theta_i)^5\\ F_{r_0} &= \left(\frac{\eta_i - \eta_t}{\eta_i + \eta_t}\right)^2 \end{aligned} \end{equation}

导体Fresnel方程
#

导体的IOR需要用复数表示, 实部描述光线速度的减小, 虚部描述光线在材质内传播时的衰减.

虚部为00时电磁波振幅如下, 只关心Euler公式分解后的实部, 此时为与距离zz相关的三角函数, α\alpha代表空间频率.

E(z)=eiαηzR(E(z))=cos(αηz) \begin{equation} \begin{aligned} E(z)&=e^{i\alpha\eta z}\\ \mathcal{R}(E(z))&=\cos(\alpha\eta z) \end{aligned} \end{equation}

当使用复数ηc=η+ik\eta_c=\eta+ik表示IOR后, 电磁波振幅会随着传播距离衰减, 形式如下.

R(E(z))=eαzkcos(αηz) \begin{equation} \begin{aligned} \mathcal{R}(E(z))=e^{-\alpha zk}\cos(\alpha\eta z) \end{aligned} \end{equation}

复数的2范数为实部与虚部和的平方, 此时可泛化上述Fresnel反射率的计算.

a+bi2=a2+b2 \begin{equation} \begin{aligned} ||a+bi||_2=\sqrt{a^2+b^2} \end{aligned} \end{equation}

导体BRDF
#

本节描述的是从光从绝缘体介质中接触导体表面时的BRDF, 只考虑光滑的情况. 光滑导体只将光线返回到一个反向, 反射光线的辐亮度由Fresnel反射率决定, 因此BRDF如下.

fr(p,ωo,ωi)=Fr(ωr)δ(ωiωr)cosθr \begin{equation} f_r(p, \omega_o, \omega_i) = F_r(\omega_r) \frac{\delta(\omega_i - \omega_r)}{|\cos\theta_r|} \end{equation}

绝缘体BSDF
#

pbrt在选择采样反射或透射时, 根据Fresnel反射率以及用户设置的Flags来决定. 由于只考虑光滑表面, BRDF和BTDF与上一节的导体BRDF都是相同的.

薄绝缘体BSDF
#

pbrt通过ThinDielectricBxDF模拟光线穿过薄绝缘体平行的内外表面的现象, 在薄导体内部多次反射后的总反射率如下.

R=R+TRT+TRRRT+=R+T2R1R2 \begin{equation} R' = R + TRT + TRRRT + \cdots = R + \frac{T^2R}{1-R^2} \end{equation}

非对称散射与折射
#

BRDF都是对称的, 即入射与反射方向可以交换, 但BTDF不是, 因为IOR的变化会导致折射后光线范围的变化, 为保持能量守恒光线的辐亮度不再保持一致.

根据能量守恒我们可以得到如下等式.

d2ϕo=d2ϕi \begin{equation} d^2\phi_o = d^2\phi_i \end{equation}

依据L=d2ϕdωdAL=\frac{d^2\phi}{\mathrm{d}\omega \mathrm{d}A^{\perp}}可以得到折射前后辐亮度的关系.

LocosθodAdωo=LicosθidAdωi \begin{equation} L_o \cos\theta_o \mathrm{d}A \mathrm{d}\omega_o = L_i \cos\theta_i \mathrm{d}A \mathrm{d}\omega_i \end{equation}

微分Snell定律可得如下关系, 其中ϕ\phi因为dϕi=dϕo\mathrm{d}\phi_i=\mathrm{d}\phi_o被抵消, sinθ\sin\theta根据Snell定律替换为η\eta.

ηocosθodθo=ηicosθidθiηocosθosinθodωodϕo=ηicosθisinθidωidϕiηo2cosθodωo=ηi2cosθidωi \begin{equation} \begin{aligned} \eta_o \cos\theta_o \mathrm{d}\theta_o &= \eta_i \cos\theta_i \mathrm{d}\theta_i\\ \eta_o \frac{\cos\theta_o}{\sin\theta_o} \frac{\mathrm{d}\omega_o}{\mathrm{d}\phi_o} &= \eta_i \frac{\cos\theta_i}{\sin\theta_i} \frac{\mathrm{d}\omega_i}{\mathrm{d}\phi_i}\\ \eta_o^2 \cos\theta_o \mathrm{d}\omega_o &= \eta_i^2 \cos\theta_i \mathrm{d}\omega_i \end{aligned} \end{equation}

将微分后的Snell定律代入可得如下关系.

Lo=ηo2ηi2Li \begin{equation} L_o = \frac{\eta_o^2}{\eta_i^2} L_i \end{equation}

由于路径追踪实际上为光线传播的逆过程, 在折射时需要考虑非对称折射的现象.

ft(p,ωi,ωo)=Lo0Li0cosθidωo=ηo2ηi2cosθidωift(p,ωo,ωi)=Li1Lo1cosθodωi=ηi2ηo2cosθodωoft(p,ωi,ωo)=ft(p,ωo,ωi)η2 \begin{equation} \begin{aligned} f_t(p, \omega_i, \omega_o) &= \frac{L_o^0}{L_i^0 \cos\theta_i \mathrm{d}\omega_o} = \frac{\eta_o^2}{\eta_i^2 \cos\theta_i \mathrm{d}\omega_i}\\ f_t(p, \omega_o, \omega_i) &= \frac{L_i^1}{L_o^1 \cos\theta_o \mathrm{d}\omega_i} = \frac{\eta_i^2}{\eta_o^2 \cos\theta_o \mathrm{d}\omega_o}\\ f_t(p, \omega_i, \omega_o) &= \frac{f_t(p, \omega_o, \omega_i)}{\eta^2} \end{aligned} \end{equation}

微表面理论
#

大部分物体表面在微观上是粗糙的, 这可以通过微表面理论模拟, 这避免了对建模精度的要求, 且更适用于Monte Carlo.

法线分布函数
#

微表面分布主要定义了法线的分布, 由于光源与观察者都与表面相距较远, 这种概率表示是可行的. 宏表面与微表面所占的面积关系如下, 即微表面沿宏观法线投影的面积与宏表面面积相等.

dAμ(ωm(p)n)dp=dAdp \begin{equation} \int_{\mathrm{d}A_\mu}(\omega_m(p) \cdot \mathbf{n}) dp = \int_{\mathrm{d}A} dp \end{equation}

将所有具有某个方向的法线的微表面在宏表面上的相对投影面积定义为法线分布函数, 此时可以得到法线分布函数的归一化性质.

ΩD(ωm)(ωmn)dωm=ΩD(ωm)cosθmdωm=1 \begin{equation} \int_\Omega D(\omega_m)(\omega_m \cdot \mathbf{n}) \mathrm{d}\omega_m = \int_\Omega D(\omega_m) \cos\theta_m \mathrm{d}\omega_m = 1 \end{equation}

若转为斜率分布, 可以得到如下关系.

P22(xm~,ym~)dxm~dym~=1 \begin{equation} \int_{-\infty}^{\infty} \int_{-\infty}^{\infty} P^{22}(x_{\tilde{m}},y_{\tilde{m}}) \mathrm{d}x_{\tilde{m}} \mathrm{d}y_{\tilde{m}}=1 \end{equation}

根据平面的定义xmx+ymy+zmz+c=0x_mx+y_my+z_mz+c=0, 法线与斜率具有如下的关系.

(xm~,ym~)=(xmzm,ymzm)=tanθm(cosϕm,sinϕm)(xm,ym,zm)=(xm~,ym~,1)xm~2+ym~2+1=(xm~,ym~,1)cosθm \begin{equation} \begin{aligned} (x_{\tilde{m}},y_{\tilde{m}})&=(-\frac{x_m}{z_m},-\frac{y_m}{z_m})=-\tan\theta_m(\cos\phi_m,\sin\phi_m)\\ (x_m, y_m, z_m)&=\frac{(-x_{\tilde{m}},-y_{\tilde{m}},1)}{\sqrt{x_{\tilde{m}}^2+y_{\tilde{m}}^2+1}}=(-x_{\tilde{m}},-y_{\tilde{m}},1)\cos\theta_m \end{aligned} \end{equation}

Jacobi行列式的计算结果如下.

dxm~dym~=sinθcos3θdθdϕ \begin{equation} \mathrm{d}x_{\tilde{m}}\mathrm{d}y_{\tilde{m}}=\frac{\sin\theta}{\cos^3\theta}\mathrm{d}\theta \mathrm{d}\phi \end{equation}

此时可以得到法线分布函数与斜率分布函数的转换关系.

D(ωm)=P22(xm~,ym~)dxm~dym~cosθsinθdθdϕ=P22(xm~,ym~)cos4θ \begin{equation} D(\omega_m) = \frac{P^{22}(x_{\tilde{m}},y_{\tilde{m}}) \mathrm{d}x_{\tilde{m}} \mathrm{d}y_{\tilde{m}}}{\cos\theta \sin\theta \mathrm{d}\theta \mathrm{d}\phi} = \frac{P^{22}(x_{\tilde{m}},y_{\tilde{m}})}{\cos^4\theta} \end{equation}

若法线分布函数为形状无关的, 即修改粗糙度等价于对法线分布函数进行拉伸, 则其斜率分布需要满足如下形式.

P22(xm~,ym~)=1αxαyf(xm~2αx2+ym~2αy2)=1αxαyf(tanθmcos2ϕmαx2+sin2ϕmαy2) \begin{equation} \begin{aligned} P^{22}(x_{\tilde{m}},y_{\tilde{m}}) &=\frac{1}{\alpha_x\alpha_y}f(\sqrt{\frac{x_{\tilde{m}^2}}{\alpha_x^2} + \frac{y_{\tilde{m}^2}}{\alpha_y^2}})\\ &=\frac{1}{\alpha_x\alpha_y}f(\tan\theta_m\sqrt{\frac{\cos^2\phi_m}{\alpha_x^2} + \frac{\sin^2\phi_m}{\alpha_y^2}}) \end{aligned} \end{equation}

对于渲染任务最常用的Trowbridge-Reitz法线分布函数定义如下.

P22(xm~,ym~)=1παxαy(1+xm~2αx2+ym~2αy2)2D(ωm)=1παxαycos4θm(1+tan2θm(cos2ϕmαx2+sin2ϕmαy2))2 \begin{equation} \begin{aligned} P^{22}(x_{\tilde{m}},y_{\tilde{m}}) &= \frac{1}{\pi\alpha_x\alpha_y(1+\frac{x_{\tilde{m}^2}}{\alpha_x^2} + \frac{y_{\tilde{m}^2}}{\alpha_y^2})^2}\\ D(\omega_m) &= \frac{1}{\pi\alpha_x\alpha_y\cos^4\theta_m(1+\tan^2\theta_m(\frac{\cos^2\phi_m}{\alpha_x^2} + \frac{\sin^2\phi_m}{\alpha_y^2}))^2} \end{aligned} \end{equation}

遮蔽函数
#

微表面可能会被遮挡, 需要通过遮蔽函数来表示某个方向上被遮蔽的比率.

ΩD(ωm)G1(ω,ωm)(ωωm)dωm=ωn=cosθ \begin{equation} \int_\Omega D(\omega_m)G_1(\omega,\omega_m)(\omega\cdot\omega_m)\mathrm{d}\omega_m=\omega\cdot\mathbf{n}=\cos\theta \end{equation}

Smith遮蔽函数认为法线与高度是独立的, 即微表面类似于一个一个浮动的小片段, 此时可以将遮蔽函数分解为局部遮蔽与全部遮蔽, 局部遮蔽只需要法线可见, 即ωωm>0\omega\cdot\omega_m>0, 此时遮蔽函数不再依赖于微表面法线. 不失一般性, 令表面为各向同性的, 法线为局部空间中的(0,0,1)(0,0,1), 视线沿xx轴为(sinθ,0,cosθ)(\sin\theta, 0, \cos\theta), 已知由于对称性xm~P2(xm~)dxm~=0\int_{-\infty}^{\infty}x_{\tilde{m}}P^{2-}(x_{\tilde{m}})\mathrm{d}x_{\tilde{m}}=0,P2(xm~)dxm~=1\int_{-\infty}^{\infty}P^{2-}(x_{\tilde{m}})\mathrm{d}x_{\tilde{m}}=1,此时可以得到如下结果.

G1(ω)=cosθΩD(ωm)max(0,ωωm)dωm=cosθΩD(ωm)cosθmmax(0,ωωm)cosθmdωm=cosθP22(xm~,ym~)max(0,(xm~sinθ+cosθ)cosθm)cosθmdxm~dym~=cosθcotθP22(xm~,ym~)(xm~sinθ+cosθ)dxm~dym~=cotθcotθP2(xm~)(xm~+cotθ)dxm~=cotθP2(xm~)xm~dxm~cotθP2(xm~)dxm~+cotθ+cotθP2(xm~)(xm~+cotθ)dxm~=11+1cotθcotθP2(xm~)(xm~cotθ)dxm~=11+Λ(ω) \begin{equation} \begin{aligned} G_1(\omega) &=\frac{\cos\theta}{\int_\Omega D(\omega_m)\max(0,\omega\cdot\omega_m)\mathrm{d}\omega_m}\\ &=\frac{\cos\theta}{\int_\Omega D(\omega_m)\cos\theta_m\frac{\max(0,\omega\cdot\omega_m)}{\cos\theta_m}\mathrm{d}\omega_m}\\ &=\frac{\cos\theta}{\int_{-\infty}^{\infty}\int_{-\infty}^{\infty}P^{22}(x_{\tilde{m}},y_{\tilde{m}}) \frac{\max(0, (-x_{\tilde{m}}\sin\theta + \cos\theta)\cos\theta_m)}{\cos\theta_m} \mathrm{d}x_{\tilde{m}} \mathrm{d}y_{\tilde{m}}}\\ &=\frac{\cos\theta}{\int_{-\infty}^{\infty}\int_{-\infty}^{\cot\theta}P^{22}(x_{\tilde{m}},y_{\tilde{m}}) (-x_{\tilde{m}}\sin\theta + \cos\theta) \mathrm{d}x_{\tilde{m}} \mathrm{d}y_{\tilde{m}}}\\ &=\frac{\cot\theta}{\int_{-\infty}^{\cot\theta}P^{2-}(x_{\tilde{m}}) (-x_{\tilde{m}} + \cot\theta) \mathrm{d}x_{\tilde{m}}}\\ &=\frac{\cot\theta}{\int_{-\infty}^{\infty}P^{2-}(x_{\tilde{m}}) x_{\tilde{m}} \mathrm{d}x_{\tilde{m}}-\cot\theta\int_{-\infty}^{\infty}P^{2-}(x_{\tilde{m}}) \mathrm{d}x_{\tilde{m}}+\cot\theta+\int_{-\infty}^{\cot\theta}P^{2-}(x_{\tilde{m}}) (-x_{\tilde{m}} + \cot\theta) \mathrm{d}x_{\tilde{m}}}\\ &=\frac{1}{1+\frac{1}{\cot\theta}\int_{\cot\theta}^{\infty}P^{2-}(x_{\tilde{m}}) (x_{\tilde{m}} - \cot\theta) \mathrm{d}x_{\tilde{m}}}\\ &=\frac{1}{1+\Lambda(\omega)} \end{aligned} \end{equation}

各向同性的Trowbridge-Reitz的Λ(ω)\Lambda(\omega)具有解析形式, 各向异性的粗糙度可以通过α=αx2cos2ϕ+αy2sin2ϕ\alpha=\sqrt{\alpha_x^2\cos^2\phi+\alpha_y^2\sin^2\phi}得到.

Λ(ω)=1cotθcotθ1πα2(1+xm~2α2+ym~2α2)2(xm~cotθ)dxm~dym~=1cotθcotθααπ(1+(xm~α)2+(ym~α)2)2(xm~αcotθα)dxm~αdym~α=1πx0x01(1+x2+y2)2(xx0)dxdy=1πx0x0(xx0)(1+x2)32dx1(1+(y1+x2)2)2dy1+x2=1πx0x0(xx0)(1+x2)32dx1(1+y2)2dy=1πx0x0(xx0)(1+x2)32dx1(1+tan2θ)2dtanθ=1πx0x0(xx0)(1+x2)32dxπ2π2cos2θ+12dθ=12x0x0(xx0)(1+x2)32dx=12x0x0(xx0)(1x)d(1+x2)12=12x0(1+x02)120x01x211dx=120(1+x02)121x0x1x2dx=12((1+x02)12x0+0(1+x02)12d1x2)=12((1+x0)12x0+x0(1+x0)121)=1+1x0212=1+α2tan2θ12 \begin{equation} \begin{aligned} \Lambda(\omega) &=\frac{1}{\cot\theta}\int_{-\infty}^{\infty}\int_{\cot\theta}^{\infty}\frac{1}{\pi\alpha^2(1+\frac{x_{\tilde{m}^2}}{\alpha^2} + \frac{y_{\tilde{m}^2}}{\alpha^2})^2} (x_{\tilde{m}} - \cot\theta)\mathrm{d}x_{\tilde{m}}\mathrm{d}y_{\tilde{m}}\\ &=\frac{1}{\cot\theta}\int_{-\infty}^{\infty}\int_{\frac{\cot\theta}{\alpha}}^{\infty}\frac{\alpha}{\pi(1+(\frac{x_{\tilde{m}}}{\alpha})^2 + (\frac{y_{\tilde{m}}}{\alpha})^2)^2} (\frac{x_{\tilde{m}}}{\alpha} - \frac{\cot\theta}{\alpha})d\frac{x_{\tilde{m}}}{\alpha}d\frac{y_{\tilde{m}}}{\alpha}\\ &=\frac{1}{\pi x_0}\int_{-\infty}^{\infty}\int_{x_0}^{\infty}\frac{1}{(1+x^2+y^2)^2}(x-x_0)dxdy\\ &=\frac{1}{\pi x_0}\int_{x_0}^{\infty}(x-x_0)(1+x^2)^{-\frac{3}{2}}\mathrm{d}x\int_{-\infty}^{\infty}\frac{1}{(1+(\frac{y}{\sqrt{1+x^2}})^2)^2}d\frac{y}{\sqrt{1+x^2}}\\ &=\frac{1}{\pi x_0}\int_{x_0}^{\infty}(x-x_0)(1+x^2)^{-\frac{3}{2}}\mathrm{d}x\int_{-\infty}^{\infty}\frac{1}{(1+y^2)^2}\mathrm{d}y\\ &=\frac{1}{\pi x_0}\int_{x_0}^{\infty}(x-x_0)(1+x^2)^{-\frac{3}{2}}\mathrm{d}x\int_{-\infty}^{\infty}\frac{1}{(1+\tan^2\theta)^2}d\tan\theta\\ &=\frac{1}{\pi x_0}\int_{x_0}^{\infty}(x-x_0)(1+x^2)^{-\frac{3}{2}}\mathrm{d}x\int_{-\frac{\pi}{2}}^{\frac{\pi}{2}}\frac{\cos2\theta+1}{2}\mathrm{d}\theta\\ &=\frac{1}{2x_0}\int_{x_0}^{\infty}(x-x_0)(1+x^2)^{-\frac{3}{2}}\mathrm{d}x\\ &=\frac{1}{2 x_0}\int_{x_0}^{\infty}(x-x_0)(-\frac{1}{x})d(1+x^2)^{-\frac{1}{2}}\\ &=\frac{1}{2 x_0}\int_{(1+x_0^2)^{-\frac{1}{2}}}^{0}\frac{x_0}{\sqrt{\frac{1}{x^2}-1}}-1\mathrm{d}x\\ &=\frac{1}{2}\int_{0}^{(1+x_0^2)^{-\frac{1}{2}}}\frac{1}{x_0}-\frac{x}{\sqrt{1-x^2}}\mathrm{d}x\\ &=\frac{1}{2}(\frac{(1+x_0^2)^{-\frac{1}{2}}}{x_0}+\int_{0}^{(1+x_0^2)^{-\frac{1}{2}}}d\sqrt{1-x^2})\\ &=\frac{1}{2}(\frac{(1+x_0)^{-\frac{1}{2}}}{x_0}+x_0(1+x_0)^{-\frac{1}{2}}-1)\\ &=\frac{\sqrt{1+\frac{1}{x_0^2}}-1}{2}\\ &=\frac{\sqrt{1+\alpha^2 \tan^2\theta}-1}{2} \end{aligned} \end{equation}

遮蔽阴影函数
#

除遮挡视线外, 光源也可能被微表面遮挡. 若采用G(ωo,ωi)=G1(ωo)G1(ωi)G(\omega_o, \omega_i)=G_1(\omega_o)G_1(\omega_i)来估计是不准确的, 例如ωo=ωi\omega_o=\omega_i的情况下是不应该被遮挡的. 通过高度相关性可以推导出更优的遮蔽阴影函数.

不失一般性, 令视线沿x轴, S(x)S(x)为视线方向从x=0x=0上某个点出发行进xx后未被遮挡的概率, g(x)dxg(x)\mathrm{d}x为光线在[x,x+dx][x,x+\mathrm{d}x]内被遮挡的概率, 此时S(x+dx)S(x + \mathrm{d}x)可以按如下方式表示.

S(x+dx)=S(x)(1g(x)dx) \begin{equation} S(x+\mathrm{d}x)=S(x)(1-g(x)\mathrm{d}x) \end{equation}

将该式视为一阶Taylor展开, 此时可以得到微分方程, S(x)S(x)可以求解.

dS(x)dx=S(x)g(x)S(x)=S(0)e0xg(x)dx \begin{equation} \begin{aligned} \frac{\mathrm{d}S(x)}{\mathrm{d}x}&=-S(x)g(x)\\ S(x)&=S(0)e^{-\int_0^x g(x)\mathrm{d}x} \end{aligned} \end{equation}

令视线在xx轴上的斜率为μv\mu_v, 表面在x轴的斜率为μ(x)\mu(x), 则S(0)S(0)定义如下, 用s(μvμ(0))s(\mu_v-\mu(0))表示.

S(0)=s(μvμ(0))={1μvμ(0)0μv<μ(0) \begin{equation} \begin{aligned} S(0)=s(\mu_v-\mu(0))= \begin{cases} 1 &\mu_v\ge\mu(0)\\ 0 &\mu_v<\mu(0) \end{cases} \end{aligned} \end{equation}

令表面高度为h(x)h(x), 条件α\alphah(x)<h(0)+μvxh(x)<h(0)+\mu_v x, 条件β\betah(x+dx)>h(0)+μv(x+dx)h(x+\mathrm{d}x)>h(0)+\mu_v\cdot(x+\mathrm{d}x), P3(h,μx)P_3(h,\mu|x)xx处斜率与高度的联合分布, 若在[x,x+dx][x,x+\mathrm{d}x]处被遮挡需要满足μ(x)>μv\mu(x)>\mu_v, 同时在Smith遮蔽函数下高度与斜率是不相关的, 此时可以定义g(x)g(x). P(α,β)P(\alpha,\beta)中对微分高度变化的积分使用微分面积计算.

g(x)=1dxP(βα)=1dxP(α,β)P(α)=1dxμvh(0)+μv(x+dx)μdxh(0)+μvxP3(h,μx)dhdμh(0)+μvxP3(h,μx)dhdμ=1dxμv(μμv)dxP3(h(0)+μvx,μx)dμh(0)+μvxP3(h,μx)dhdμ=μv(μμv)Ph(h(0)+μvx)P2(μ)dμh(0)+μvxPh(h)dh=Λ(μv)μvPh(h(0)+μvx)f(h(0)+μvx) \begin{equation} \begin{aligned} g(x) &=\frac{1}{\mathrm{d}x}P(\beta|\alpha)\\ &=\frac{1}{\mathrm{d}x}\frac{P(\alpha,\beta)}{P(\alpha)}\\ &=\frac{1}{\mathrm{d}x}\frac{\int_{\mu_v}^\infty\int_{h(0)+\mu_v(x+\mathrm{d}x)-\mu \mathrm{d}x}^{h(0)+\mu_vx}P_3(h,\mu|x)dh \mathrm{d}\mu}{\int_{-\infty}^{\infty}\int_{-\infty}^{h(0)+\mu_vx}P_3(h,\mu|x)dhd\mu}\\ &=\frac{1}{\mathrm{d}x}\frac{\int_{\mu_v}^\infty(\mu-\mu_v)dxP_3(h(0)+\mu_vx,\mu|x)\mathrm{d}\mu}{\int_{-\infty}^{\infty}\int_{-\infty}^{h(0)+\mu_vx}P_3(h,\mu|x)dhd\mu}\\ &=\frac{\int_{\mu_v}^\infty(\mu-\mu_v)P_h(h(0)+\mu_vx)P^{2-}(\mu)\mathrm{d}\mu}{\int_{-\infty}^{h(0)+\mu_vx}P_h(h)dh}\\ &=\Lambda(\mu_v)\frac{\mu_vP_h(h(0)+\mu_vx)}{f(h(0)+\mu_vx)} \end{aligned} \end{equation}

在Smith遮蔽函数下s(μvμ(0))s(\mu_v-\mu(0))恒成立, 省去该项后可以得到不会被遮蔽的概率S(h)S(h).

S(h,ω)=eΛ(ω)0μvPh(h+μvx)f(h+μvx)dx=eΛ(ω)[lnf(h+μvx)]0=eΛ(ω)(ln1lnf(h))=eΛ(ω)lnf(h)=f(h)Λ(ω) \begin{equation} \begin{aligned} S(h, \omega) &= e^{-\Lambda(\omega)\int_0^{\infty}\frac{\mu_vP_h(h+\mu_vx)}{f(h+\mu_vx)}\mathrm{d}x}\\ &= e^{-\Lambda(\omega)\left[\ln f(h+\mu_v x)\right]_0^{\infty}}\\ &= e^{-\Lambda(\omega)(\ln 1 - \ln f(h))}\\ &= e^{\Lambda(\omega)\ln f(h)}\\ &= f(h)^{\Lambda(\omega)} \end{aligned} \end{equation}

此时可以得到Smith遮蔽函数的全局项, 可以看到与上一节的证明结果是相同的.

G1(ω)=f(h)Λ(ω)Ph(h)dh=f(h)Λ(ω)df(h)=[f(h)1+Λ(ω)1+Λ(ω)]=11+Λ(ω) \begin{equation} \begin{aligned} G_1(\omega) &= \int_{-\infty}^{\infty} f(h)^{\Lambda(\omega)} P_h(h) dh\\ &= \int_{-\infty}^{\infty} f(h)^{\Lambda(\omega)} df(h)\\ &= \left[\frac{f(h)^{1+\Lambda(\omega)}}{1+\Lambda(\omega)}\right]_{-\infty}^{\infty}\\ &= \frac{1}{1+\Lambda(\omega)} \end{aligned} \end{equation}

此时可以推导出遮蔽阴影函数.

G(ωo,ωi)=f(h)Λ(ωo)Ph(h)dh+f(h)Λ(ωi)Ph(h)dh=f(h)Λ(ωo)+Λ(ωi)Ph(h)dh=11+Λ(ωo)+Λ(ωi) \begin{equation} \begin{aligned} G(\omega_o,\omega_i) &= \int_{-\infty}^{\infty}f(h)^{\Lambda(\omega_o)}P_h(h)dh + \int_{-\infty}^{\infty}f(h)^{\Lambda(\omega_i)}P_h(h)dh\\ &= \int_{-\infty}^{\infty}f(h)^{\Lambda(\omega_o)+\Lambda(\omega_i)}P_h(h)dh\\ &= \frac{1}{1+\Lambda(\omega_o)+\Lambda(\omega_i)} \end{aligned} \end{equation}

采样可见法线分布
#

根据法线分布函数与遮蔽阴影函数我们可以得到视线为ω\omega时法线的分布.

Dω(ωm)=G1(ω)cosθD(ωm)max(0,ωωm) \begin{equation} D_\omega(\omega_m)=\frac{G_1(\omega)}{\cos\theta}D(\omega_m)\max(0,\omega\cdot\omega_m) \end{equation}

由于逆变换法没有解析形式, pbrt将Trowbridge-Reitz分布看作一个被缩放的半球, 投影到半球上为椭圆. 因此将法线变换到zz轴, 对视线方向乘上由各向异性粗糙度定义的椭圆轴长, 执行逆椭圆变换, 在半球中采样更为简单.

// Transform _w_ to hemispherical configuration
Vector3f wh = Normalize(Vector3f(alpha_x * w.x, alpha_y * w.y, w.z));
if (wh.z < 0)
    wh = -wh;

构造以视线为zz轴的正交坐标系, T2轴保证采样到缩放半圆的法线在该轴为负.

// Find orthonormal basis for visible normal sampling
Vector3f T1 = (wh.z < 0.99999f) ? Normalize(Cross(Vector3f(0, 0, 1), wh))
                                : Vector3f(1, 0, 0);
Vector3f T2 = Cross(wh, T1);

将半球投影到xyxy平面时, 只有一侧是完整半圆, 另一侧是缩放了cosθ=nω\cos\theta=\mathbf{n}\cdot\omegawh.z的半圆. 令h=1x2h=\sqrt{1-x^2}, 原本采样得到的xx对应的yy范围为(h,h)(-h, h), 缩放后为(hcosθ,h)(-h\cos\theta, h), 相当于y=1+cosθ2y+h(1cosθ)2y'=\frac{1+\cos\theta}{2}y+\frac{h(1-\cos\theta)}{2}, pbrt这里的Lerp与之等价.

// Generate uniformly distributed points on the unit disk
Point2f p = SampleUniformDiskPolar(u);

// Warp hemispherical projection for visible normal sampling
Float h = std::sqrt(1 - Sqr(p.x));
p.y = Lerp((1 + wh.z) / 2, h, p.y);

最后将采样得到的法线变换回原本的空间, 由于法线的变换为逆变换的转置, 这里仍然乘上粗糙度.

// Reproject to hemisphere and transform normal to ellipsoid configuration
Float pz = std::sqrt(std::max<Float>(0, 1 - LengthSquared(Vector2f(p))));
Vector3f nh = p.x * T1 + p.y * T2 + pz * wh;
CHECK_RARE(1e-5f, nh.z == 0);
return Normalize(
    Vector3f(alpha_x * nh.x, alpha_y * nh.y, std::max<Float>(1e-6f, nh.z)));

实时渲染IBL的重要性抽样中, 法线与视线方向是一致的, 因此可以对下式进行球面坐标上的重要性抽样.

ππ0π2D(θ,ϕ)cosθsinθdθdϕ=1 \begin{equation} \int_{-\pi}^{\pi}\int_0^{\frac{\pi}{2}}D(\theta,\phi)\cos\theta\sin\theta \mathrm{d}\theta \mathrm{d}\phi = 1 \end{equation}

各向同性的Trowbridge-Reitz在θ,ϕ\theta,\phi上的PDF如下.

p(θ)=02πD(θ,ϕ)cosθsinθdϕ=02π1πα2cos4θ(1+tan2θα2)2cosθsinθdϕ=2α2cosθsinθcos4θ(α2+tan2θ)2=2α2cosθsinθ(α2cos2θ+sin2θ)2=2α2cosθsinθ((α21)cos2θ+1)2p(ϕ)=p(θ,ϕ)p(θ)=12π \begin{equation} \begin{aligned} p(\theta) &=\int_{0}^{2\pi}D(\theta,\phi)\cos\theta\sin\theta \mathrm{d}\phi\\ &=\int_{0}^{2\pi}\frac{1}{\pi\alpha^2\cos^4\theta(1+\frac{\tan^2\theta}{\alpha^2})^2}\cos\theta\sin\theta \mathrm{d}\phi\\ &=\frac{2\alpha^2\cos\theta\sin\theta}{\cos^4\theta(\alpha^2+\tan^2\theta)^2}\\ &=\frac{2\alpha^2\cos\theta\sin\theta}{(\alpha^2\cos^2\theta+\sin^2\theta)^2}\\ &=\frac{2\alpha^2\cos\theta\sin\theta}{((\alpha^2-1)\cos^2\theta+1)^2}\\ p(\phi)&=\frac{p(\theta,\phi)}{p(\theta)}=\frac{1}{2\pi} \end{aligned} \end{equation}

由于逆变换法的需要, 计算二者的CDF.

P(θ)=0θp(θ0)dθ0=0θ2α2cosθ0((α21)cos2θ0+1)2dcosθ0=1cosθ2α2x((α21)x2+1)2dx=1cosθα2(α21)d1(α21)x2+1=α2(α21)(1(α21)cos2θ+11α2)=1cos2θ((α21)cos2θ+1)P(ϕ)=0ϕp(ϕ0)dϕ0=ϕ2π \begin{equation} \begin{aligned} P(\theta) &=\int_0^{\theta}p(\theta_0)\mathrm{d}\theta_0\\ &=\int_0^{\theta}\frac{-2\alpha^2\cos\theta_0}{((\alpha^2-1)\cos^2\theta_0+1)^2}d\cos\theta_0\\ &=\int_1^{\cos\theta}\frac{-2\alpha^2x}{((\alpha^2-1)x^2+1)^2}\mathrm{d}x\\ &=\int_1^{\cos\theta}\frac{\alpha^2}{(\alpha^2-1)}d\frac{1}{(\alpha^2-1)x^2+1}\\ &=\frac{\alpha^2}{(\alpha^2-1)}(\frac{1}{(\alpha^2-1)\cos^2\theta+1}-\frac{1}{\alpha^2})\\ &=\frac{1-\cos^2\theta}{((\alpha^2-1)\cos^2\theta+1)}\\ P(\phi) &=\int_0^{\phi}p(\phi_0)\mathrm{d}\phi_0=\frac{\phi}{2\pi} \end{aligned} \end{equation}

通过逆变换法得到最终变换.

θ=P1(u0)=cos11u0(α21)u0+1ϕ=P1(u1)=2πu1 \begin{equation} \begin{aligned} \theta &=P^{-1}(u_0) =\cos^{-1}\sqrt{\frac{1-u_0}{(\alpha^2-1)u_0+1}}\\ \phi &=P^{-1}(u_1) =2\pi u_1 \end{aligned} \end{equation}

Torrance-Sparrow模型
#

综合以上结论我们可以推导出微表面上的Torrance-Sparrow BRDF并应用于材质中.

半向量变换
#

对于镜面反射表面法线ωm\omega_m是位于ωo\omega_oωo\omega_o之间的, 因此也可以被称为半向量. 以ωo\omega_o为中心即θo=0\theta_o=0, 此时可以获取Jacobi行列式的变换结果.

dωmdωi=sinθmdθmdϕmsinθidθidϕi=sinθmdθmdϕmsin2θm2dθmdϕm=sinθm4cosθmsinθm=14(ωiωm)=14(ωoωm) \begin{equation} \begin{aligned} \frac{\mathrm{d}\omega_m}{\mathrm{d}\omega_i} &= \frac{\sin\theta_m \mathrm{d}\theta_m \mathrm{d}\phi_m}{\sin\theta_i \mathrm{d}\theta_i \mathrm{d}\phi_i}\\ &= \frac{\sin\theta_m \mathrm{d}\theta_m \mathrm{d}\phi_m}{\sin2\theta_m 2\mathrm{d}\theta_m \mathrm{d}\phi_m}\\ &= \frac{\sin\theta_m}{4\cos\theta_m\sin\theta_m}\\ &= \frac{1}{4(\omega_i\cdot\omega_m)}\\ &= \frac{1}{4(\omega_o\cdot\omega_m)} \end{aligned} \end{equation}

Torrance-Sparrow PDF
#

ωi\omega_i的分布如下.

p(ωi)=Dωo(ωm)dωmdωi=Dωo(ωm)4(ωoωm) \begin{equation} p(\omega_i)=D_{\omega_o}(\omega_m)\frac{\mathrm{d}\omega_m}{\mathrm{d}\omega_i}=\frac{D_{\omega_o}(\omega_m)}{4(\omega_o\cdot\omega_m)} \end{equation}

Torrance-Sparrow BRDF
#

在Monte Carlo下反射方程可以做如下近似.

Lo(p,ωo)=Ωfr(p,ωo,ωi)Li(p,ωi)cosθidωifr(p,ωo,ωi)Li(p,ωi)cosθip(ωi)=F(ωoωm)G(ωi,ωo)Li(p,ωi) \begin{equation} \begin{aligned} L_o(p,\omega_o) &=\int_\Omega f_r(p,\omega_o,\omega_i)L_i(p,\omega_i)\cos\theta_id\omega_i\\ &\approx \frac{f_r(p,\omega_o,\omega_i)L_i(p,\omega_i)\cos\theta_i}{p(\omega_i)}\\ &=F(\omega_o\cdot\omega_m)G(\omega_i,\omega_o)L_i(p,\omega_i) \end{aligned} \end{equation}

由此可得Torrance-Sparrow BRDF.

fr(p,ωo,ωi)=Dωo(ωm)F(ωo,ωm)G(ωi)4(ωoωm)cosθi=D(ωm)F(ωo,ωm)G(ωi)G(ωo)4cosθicosθoD(ωm)F(ωo,ωm)G(ωi,ωo)4cosθicosθo \begin{equation} \begin{aligned} f_r(p,\omega_o,\omega_i) &=\frac{D_{\omega_o}(\omega_m)F(\omega_o,\omega_m)G(\omega_i)}{4(\omega_o\cdot\omega_m)\cos\theta_i}\\ &=\frac{D(\omega_m)F(\omega_o,\omega_m)G(\omega_i)G(\omega_o)}{4\cos\theta_i\cos\theta_o}\\ &\approx\frac{D(\omega_m)F(\omega_o,\omega_m)G(\omega_i, \omega_o)}{4\cos\theta_i\cos\theta_o} \end{aligned} \end{equation}

Torrance-Sparrow采样
#

Sample_wm得到的ωi\omega_i朝向表面下方, 这意味着反射后仍然位于微表面, 需要执行多次散射. pbrt不考虑这种情况, 显然在极为粗糙的表面这会导致能量损失.

Vector3f wm = mfDistrib.Sample_wm(wo, u);
Vector3f wi = Reflect(wo, wm);
if (!SameHemisphere(wo, wi))
    return {};

粗糙绝缘体BSDF
#

粗糙绝缘体PDF
#

根据Snell定律我们可以把投影到与半向量垂直的平面上的部分抵消, 由此可得以下关系. 此时得到的半向量总是指向光学密度较大的一侧, 需要后续修正. 对于反射由于ηi=ηo\eta_i=\eta_o这与半向量是等价的.

ωm=ηiωi+ηoωoηiωi+ηoωo=ηωi+ωoηωi+ωo \begin{equation} \omega_m=\frac{\eta_i\omega_i+\eta_o\omega_o}{\Vert\eta_i\omega_i+\eta_o\omega_o\Vert}=\frac{\eta\omega_i+\omega_o}{\Vert\eta\omega_i+\omega_o\Vert} \end{equation}

此时Jacobi行列式结果如下, 这可以由几何关系推导得到, 具体见Water et al. 2007.

dωmdωi=ωiωmηi2((ηiωi+ηoωo)ωm)2=ωiωm((ωiωm)+(ωoωm)η)2 \begin{equation} \begin{aligned} \frac{\mathrm{d}\omega_m}{\mathrm{d}\omega_i} &=\frac{|\omega_i\cdot\omega_m|\eta_i^2}{((\eta_i\omega_i+\eta_o\omega_o)\cdot\omega_m)^2}\\ &=\frac{|\omega_i\cdot\omega_m|}{((\omega_i\cdot\omega_m)+\frac{(\omega_o\cdot\omega_m)}{\eta})^2} \end{aligned} \end{equation}

refract-jacobi

粗糙绝缘体BSDF
#

根据PDF可以将Torrance-Sparrow BRDF拓展到BTDF, 得到完整的BSDF.

ft(p,ωo,ωi)=Dωo(ωm)(1F(ωoωm))G(ωi)ωiωm((ωiωm)+(ωoωm)η)2cosθi=D(ωm)(1F(ωoωm))G(ωi,ωo)((ωiωm)+(ωoωm)η)2ωiωmωoωmcosθicosθo \begin{equation} \begin{aligned} f_t(p,\omega_o,\omega_i) &=\frac{D_{\omega_o}(\omega_m)(1-F(\omega_o\cdot\omega_m))G(\omega_i)|\omega_i\cdot\omega_m|}{((\omega_i\cdot\omega_m)+\frac{(\omega_o\cdot\omega_m)}{\eta})^2|\cos\theta_i|}\\ &=\frac{D(\omega_m)(1-F(\omega_o\cdot\omega_m))G(\omega_i,\omega_o)}{((\omega_i\cdot\omega_m)+\frac{(\omega_o\cdot\omega_m)}{\eta})^2}\frac{|\omega_i\cdot\omega_m||\omega_o\cdot\omega_m|}{|\cos\theta_i||\cos\theta_o|} \end{aligned} \end{equation}

粗糙绝缘体采样
#

与之前章节描述的一样, 对法线进行重要性抽样并随机选取反射或折射.

塑料BSDF
#

塑料BSDF被建模为漫反射基础表面涂上较薄的绝缘体层, 与薄绝缘体模型类似, 塑料BSDF需要求解所有可能的内部反射情况之和.

光滑塑料
#

假设涂层为光滑表面, 对于只在内部漫反射一次的情况, 由于表面光滑, 漫反射的出射方向是确定的, 使用Dirac delta函数表示, 使用微分Snell定律计算Jacobian, 此时结果如下, 其中θit\theta_{it}θot\theta_{ot}为折射后与法线的夹角.

Lo=Ω(1F(ωn))Lωη2cos(ωn)δ(ωot)cos(ωotn)dω=(1F(ωon))Lotη2=(1F(ωon))η2ΩitRπLωitcosωitdωit=(1F(ωon))η2Ωi(1F(ωin))RπLωi1η2cosωiη2dωi=(1F(ωon))(1F(ωin))η2ΩiRπLωicosωidωi \begin{equation} \begin{aligned} L_o &=\int_{\Omega} (1 - F(\omega\cdot\mathbf{n})) L_\omega \eta^2 \cos(\omega\cdot\mathbf{n}) \frac{\delta(\omega_{ot})}{\cos(\omega_{ot}\cdot\mathbf{n})} \mathrm{d}\omega\\ &=(1 - F(\omega_{o}\cdot\mathbf{n})) L_{ot} \eta^2\\ &=(1 - F(\omega_{o}\cdot\mathbf{n})) \eta^2 \int_{\Omega_{it}} \frac{R}{\pi} L_{\omega_{it}} \cos\omega_{it} \mathrm{d}\omega_{it}\\ &=(1 - F(\omega_{o}\cdot\mathbf{n})) \eta^2 \int_{\Omega_{i}} (1 - F(\omega_{i}\cdot\mathbf{n})) \frac{R}{\pi} L_{\omega_{i}} \frac{1}{\eta^2} \cos\omega_{i} \eta^2 \mathrm{d}\omega_{i}\\ &=(1 - F(\omega_{o}\cdot\mathbf{n})) (1 - F(\omega_{i}\cdot\mathbf{n})) \eta^2 \int_{\Omega_{i}} \frac{R}{\pi} L_{\omega_{i}} \cos\omega_{i} \mathrm{d}\omega_{i}\\ \end{aligned} \end{equation}

整理为BSDF可得如下结果.

fr(p,ωo,ωi)=(1F(ωon))(1F(ωin))η2Rπ=FtRπ \begin{equation} \begin{aligned} f_r(p, \omega_o, \omega_i) &=(1 - F(\omega_{o}\cdot\mathbf{n})) (1 - F(\omega_{i}\cdot\mathbf{n})) \eta^2 \frac{R}{\pi}\\ &=F_t \frac{R}{\pi}\\ \end{aligned} \end{equation}

对于漫反射+镜面反射+漫反射的情况, 令ω\omega为漫反射的出射方向, 由于表面光滑在镜面反射阶段的余弦项为ωn\omega\cdot\mathbf{n}, 积分结果如下.

fr(p,ωo,ωi)=FtRπωRπF(ωn)cosθdω=FtRπ02π0π2RπF(cosθ)sinθcosθdθdϕ=Ft2R2π0π2F(cosθ)sinθcosθdθ=Ft2R2π0π2F(cosθ)2dcos2θ=FtR2π01F(x)dx=FtFrR2π \begin{equation} \begin{aligned} f_r(p, \omega_o, \omega_i) &= F_t \frac{R}{\pi} \int_\omega \frac{R}{\pi} F(\omega \cdot \mathbf{n}) \cos\theta \mathrm{d}\omega\\ &= F_t \frac{R}{\pi} \int_0^{2\pi} \int_0^{\frac{\pi}{2}} \frac{R}{\pi} F(\cos\theta) \sin\theta \cos\theta \mathrm{d}\theta \mathrm{d}\phi\\ &= F_t \frac{2R^2}{\pi} \int_0^{\frac{\pi}{2}} F(\cos\theta) \sin\theta \cos\theta \mathrm{d}\theta\\ &= F_t \frac{2R^2}{\pi} \int_0^{\frac{\pi}{2}} -\frac{F(\cos\theta)}{2} d\cos^2\theta\\ &= F_t \frac{R^2}{\pi} \int_0^1 F(\sqrt{x}) \mathrm{d}x\\ &= F_t \frac{F_r R^2}{\pi} \end{aligned} \end{equation}

递推任意次反射, 不考虑表面反射, 结果如下. 重要性抽样可以使用余弦加权半球采样, 因为1F(ωn)1-F(\omega\cdot\mathbf{n})cosθ\cos\theta的梯度方向一致.

fr(p,ωo,ωi)=n=0FtRn+1Frnπ=FtπR1RFr \begin{equation} \begin{aligned} f_r(p, \omega_o, \omega_i) &= \sum_{n=0}^\infty F_t \frac{R^{n+1} F_r^n}{\pi}\\ &= \frac{F_t}{\pi} \frac{R}{1-RF_r} \end{aligned} \end{equation}

粗糙塑料
#

对与带有微表面的涂层, 我们仍然首先证明单次漫反射, 由于BSDF可逆和积分顺序可交换, 最终结果如下.

Lo=Ωotfo(p,ωo,ωot)Lωotη2cos(ωotn)dωot=Ωotfo(p,ωo,ωot)cos(ωotn)η2dωotΩitRπLωitcos(ωitn)dωit=η2RπT(ωo)ΩitΩifi(p,ωit,ωi)Lωicos(ωin)cos(ωitn)dωidωit=η2RπT(ωo)Ωitfi(p,ωit,ωi)cos(ωitn)dωitΩiLωicos(ωin)dωi=η2RπT(ωo)ΩiT(ωi)Lωicos(ωin)dωi \begin{equation} \begin{aligned} L_o &=\int_{\Omega_{ot}} f_o(p, \omega_o, \omega_{ot}) L_{\omega_{ot}} \eta^2 \cos(\omega_{ot}\cdot\mathbf{n}) \mathrm{d}\omega_{ot}\\ &=\int_{\Omega_{ot}} f_o(p, \omega_o, \omega_{ot}) \cos(\omega_{ot}\cdot\mathbf{n}) \eta^2 \mathrm{d}\omega_{ot} \int_{\Omega_{it}} \frac{R}{\pi} L_{\omega_{it}} \cos(\omega_{it}\cdot\mathbf{n}) \mathrm{d}\omega_{it}\\ &=\eta^2 \frac{R}{\pi} T(\omega_o) \int_{\Omega_{it}} \int_{\Omega_{i}} f_i(p, \omega_{it}, \omega{i}) L_{\omega_{i}} \cos(\omega_{i}\cdot\mathbf{n}) \cos(\omega_{it}\cdot\mathbf{n}) \mathrm{d}\omega_{i} \mathrm{d}\omega_{it}\\ &=\eta^2 \frac{R}{\pi} T(\omega_o) \int_{\Omega_{it}} f_i(p, \omega_{it}, \omega{i}) \cos(\omega_{it}\cdot\mathbf{n}) \mathrm{d}\omega_{it} \int_{\Omega_{i}} L_{\omega_{i}} \cos(\omega_{i}\cdot\mathbf{n}) \mathrm{d}\omega_{i}\\ &=\eta^2 \frac{R}{\pi} T(\omega_o) \int_{\Omega_{i}} T(\omega_i) L_{\omega_{i}} \cos(\omega_{i}\cdot\mathbf{n}) \mathrm{d}\omega_{i}\\ \end{aligned} \end{equation}

整理为BSDF可得如下结果, 后续过程不再证明, 与光滑情况下结果类似. 透射率与反射率可做预计算, 比如mitsuba3的实现. 若材质处理计算量大, 可用Fresnel替换, 比如tungsten的实现.

fr(p,ωo,ωi)=η2RπT(ωi)T(ωo)=FtRπ \begin{equation} \begin{aligned} f_r(p, \omega_o, \omega_i) &= \eta^2 \frac{R}{\pi} T(\omega_i) T(\omega_o) &= F_t \frac{R}{\pi} \end{aligned} \end{equation}

BSDF测量值
#

现实世界中的很多材质无法通过微表面模型表达, pbrt采用测量值来实现数据驱动的反射模型, 通过采样估计的粗糙度对应的法线分布来提高测量效率.

测量过程
#

参数化测量
#

由于测量出的BRDF在量级上可能差距较大, 不适合线性插值, pbrt将采样值变换为Monte Carlo权重的形式再插值.

M(k)=fr(ωo,ωi(k))cosθi(k)p(ωi(k)) \begin{equation} M^{(k)} = \frac{f_r(\omega_o, \omega_i^{(k)})\cos\theta_i^{(k)}}{p(\omega_i^{(k)})} \end{equation}

BRDF求解
#

MM为样本插值, R(ωo,u)=ωiR(\omega_o, u)=\omega_i为重要性抽样, 数据驱动的BRDF可以按如下方式表示.

fr(ωo,ωi)=M(R1(ωo,ωi))p(ωi)cosθi \begin{equation} f_r(\omega_o,\omega_i)=\frac{M(R^{-1}(\omega_o,\omega_i))p(\omega_i)}{\cos\theta_i} \end{equation}

泛化微表面模型
#

对于测量值BRDF, 可以使用最基本的Smith遮蔽函数的定义来得到PDF, 因为可以通过数值积分计算这里不采用Smith遮蔽函数的解析形式.

p(ωi)=Dωo(ωm)4(ωoωm)=D(ωm)max(0,ωoωm)4(ωoωm)ΩD(ω)max(0,ωo,ω)dω=D(ωm)4σ(ωo) \begin{equation} \begin{aligned} p(\omega_i) &= \frac{D_{\omega_o}(\omega_m)}{4(\omega_o\cdot\omega_m)}\\ &= \frac{D(\omega_m)\max(0,\omega_o\cdot\omega_m)}{4(\omega_o\cdot\omega_m)\int_\Omega D(\omega)\max(0,\omega_o,\omega)\mathrm{d}\omega}\\ &= \frac{D(\omega_m)}{4\sigma(\omega_o)} \end{aligned} \end{equation}

此时可以求解BRDF.

fr(ωo,ωi)=M(R1(ωo,ωi))D(ωm)4σ(ωo)cosθi \begin{equation} f_r(\omega_o,\omega_i)=\frac{M(R^{-1}(\omega_o,\omega_i))D(\omega_m)}{4\sigma(\omega_o)\cos\theta_i} \end{equation}

初始微表面模型
#

法线分布函数只有两个维度, 不会有维度组合数量的问题, 因此可以通过估计D(ω)D(\omega)来获取初始微表面模型. 对于右侧的积分, 可以先测量fr(p,ωj,ωj)f_r(p, \omega_j, \omega_j)作为D(ωj)D(\omega_j)的估计, 即不考虑遮蔽函数.

fr(p,ω,ω)=D(ω)F(ωω)G(ω,ω)4cos2θD(ω)G1(ω)cos2θD(ω)fr(p,ω,ω)cosθΩD(ωm)max(0,ωωm)dωm \begin{equation} \begin{aligned} f_r(p,\omega,\omega)&=\frac{D(\omega)F(\omega\cdot\omega)G(\omega,\omega)}{4\cos^2\theta}\propto\frac{D(\omega)G_1(\omega)}{\cos^2\theta}\\ D(\omega)&\propto f_r(p,\omega,\omega)\cos\theta\int_\Omega D(\omega_m)\max(0,\omega\cdot\omega_m)\mathrm{d}\omega_m \end{aligned} \end{equation}

基础数据结构
#

通过PiecewiseLinear2D实现插值与采样.

struct MeasuredBxDFData {
    // MeasuredBxDFData Public Members
    pstd::vector<float> wavelengths;
    PiecewiseLinear2D<3> spectra;
    PiecewiseLinear2D<0> ndf;
    PiecewiseLinear2D<2> vndf;
    PiecewiseLinear2D<0> sigma;
    bool isotropic;
    PiecewiseLinear2D<2> luminance;
    MeasuredBxDFData(Allocator alloc)
        : ndf(alloc),
          sigma(alloc),
          vndf(alloc),
          luminance(alloc),
          spectra(alloc),
          wavelengths(alloc) {}

    static MeasuredBxDFData *Create(const std::string &filename, Allocator alloc);

    std::string ToString() const {
        return StringPrintf("[ MeasuredBxDFData filename: %s ]", filename);
    }

    std::string filename;
};

求解
#

MeasuredBxDF中存储MeasuredBxDFData指针并实现相应的功能.

毛发散射
#

各个波长在毛发上的反射率是类似的, 因此毛发的颜色主要由吸收的折射光的量决定. 这可以通过DielectricBxDF与体渲染结合实现, 但这种方式计算量较大且无法实现重要性抽样. 特化的毛发BSDF可以解决该问题.

几何
#

毛发通过Curve实现, pbrt假设毛发为朝向入射光的带状曲面, 毛发BSDF基于圆柱形曲面, 在毛发不相互交织且不比像素宽很多的情况下, 这种转换是可行的.

对于光线与圆柱曲面的交点u,vu,v, uu上的法线都位于同一平面, 此时令pu\frac{\partial p}{\partial u}xx轴, pv\frac{\partial p}{\partial v}yy轴, 入射光线可以转为纵向角与方位角, 即与xx的夹角为θ\theta, yzyz平面中与yy的夹角为ϕ\phi, 由于圆柱曲面的性质光线是位于yzyz平面的.

θ=π2cos1(ωx)ϕ=πsign(ωz)(πcos1(ωy)) \begin{equation} \begin{aligned} \theta &= \frac{\pi}{2}-\cos^{-1}(\omega\cdot x)\\ \phi &= \pi-\text{sign}(\omega\cdot z)(\pi - \cos^{-1}(\omega\cdot y)) \end{aligned} \end{equation}

根据vv的定义, 交点距离圆心的距离为1+2v-1+2v, 此时可以得到光线与法线的夹角γ\gamma.

γ=sin1(1+2v) \begin{equation} \gamma = \sin^{-1}(-1+2v) \end{equation}

毛发散射
#

毛发包含发鳞, 发皮质, 发髓三个部分, 发髓由一些列表面的凸起构成, 发皮质与发髓包含吸收光的色素, 以发髓的颜色为主. pbrt假设毛发表面是与圆柱夹角为α\alpha的圆锥状凸起, 毛发内部为同一介质即不产生内部散射. 同时pbrt假设光线在毛发上的相同位置入射与出射, 此时可以使用BSDF.

光线会在毛发内部多次反射与折射, 令pp为光线进入空气前反射或折射的次数, 例如p=0p=0为第一次反射RR, p=1p=1为第二次折射TTTT, p=3p=3TRTTRT. 此时BSDF可以写为如下形式, 其中MpM_p为纵向散射方程, NpN_p为方位散射方程, ApA_p为衰减方程, 分母用于抵消Kajiya中的余弦项. pbrt只计算p3p\le 3的BSDF, 余项合并为一项.

f(ωo,ωi)=p=0fp(ωo,ωi)=p=0Mp(θo,θi)Ap(ωo)Np(ϕ)cosθi \begin{equation} \begin{aligned} f(\omega_o,\omega_i) &=\sum_{p=0}^{\infty} f_p(\omega_o,\omega_i)\\ &=\sum_{p=0}^{\infty} \frac{M_p(\theta_o,\theta_i)A_p(\omega_o)N_p(\phi)}{\cos\theta_i}\\ \end{aligned} \end{equation}

HairBxDF构造函数如下, 其中hh为与曲线中心的偏移, η\eta为相对IOR, σa\sigma_a为毛发内部的吸收率系数(吸收率与光线传播距离有关, 后续体渲染章节会介绍), βm\beta_m为纵向粗糙度, βn\beta_n为方位粗糙度, α\alpha为毛发表面凸起的夹角.

PBRT_CPU_GPU
HairBxDF(Float h, Float eta, const SampledSpectrum &sigma_a, Float beta_m,
         Float beta_n, Float alpha);

纵向散射
#

纵向散射方程如下, 其中I0I_0为第一类Bessel方程的修改, vv为粗糙度.

Mp(θo,θi)=esinθisinθov2vsinh(1v)I0(cosθocosθiv) \begin{equation} M_p(\theta_o,\theta_i)=\frac{e^{-\frac{\sin\theta_i\sin\theta_o}{v}}}{2v\text{sinh}(\frac{1}{v})}I_0(\frac{\cos\theta_o\cos\theta_i}{v}) \end{equation}

pbrt根据βm\beta_m计算不同pp下的粗糙度.

v0=(0.726βm+0.812βm2+3.7βm20)2v1=0.25v0v2=v3==vmax=4v0 \begin{equation} \begin{aligned} v_0 &= (0.726\beta_m+0.812\beta_m^2+3.7\beta_m^20)^2\\ v_1 &= 0.25v_0\\ v_2 &= v_3 = \cdots = v_{\max} = 4v_0 \end{aligned} \end{equation}

纤维吸收
#

吸收率受光线传播距离影响, 这需要计算折射光线的纵向角与方位角. 纵向角可以通过Snell定律获取, 方位角可以通过将ωt\omega_t投影到yzyz平面计算, 也可以使用修改后的IOR通过Snell定律计算.

η=η2sin2θocosθo \begin{equation} \eta'=\frac{\sqrt{\eta^2-\sin^2\theta_o}}{\cos\theta_o} \end{equation}

根据直线与圆相交的性质可以得到在yzyz传播的距离, 除以纵向角的余弦即可获取传播距离.

l=2cosγtcosθt \begin{equation} l=\frac{2\cos\gamma_t}{\cos\theta_t} \end{equation}

利用后面体渲染章节介绍的Beer定律可以得到经过吸收后的透射率.

Tr=eσal \begin{equation} T_r=e^{-\sigma_a l} \end{equation}

此时可以得到ApA_p的定义, 余项可以通过通项公式得到.

Ap={Ap1Tf=(1f)2Tpfp1p>0fp=0 \begin{equation} \begin{aligned} A_p&= \begin{cases} A_{p-1}Tf=(1-f)^2 T^p f^{p-1} & p>0\\ f & p=0 \end{cases} \end{aligned} \end{equation} p=pmax(1f)2Tpfp1=(1f)2Tpmaxfpmax11Tf \begin{equation} \sum_{p=p_{\max}}^{\infty}(1-f)^2 T^p f^{p-1}=\frac{(1-f)^2 T^{p_{\max}} f^{p_{\max}-1}}{1-Tf} \end{equation}

方位散射
#

方位散射只需要考虑ϕ\phi, 即只需要考虑投影到yzyz平面上的圆, 以顺时针为正, 此时可以得到每次出射时的角度变化.

ϕ(p,h)=2pγt2γo+pπ \begin{equation} \phi(p,h)=2p\gamma_t-2\gamma_o+p\pi \end{equation}

对于粗糙度, pbrt选用截尾Logistic分布, 与Gaussian分布相比Logistic具有相似的形状且具有积分解析式.

lt(x,s,[a,b])=l(x,s)abl(x,s)dx \begin{equation} l_t(x,s,[a,b])=\frac{l(x,s)}{\int_a^b l(x',s)\mathrm{d}x'} \end{equation}

pbrt根据βn\beta_n计算ss.

s=π8(0.265βn+1.194βn2+5.372βn22) \begin{equation} s=\sqrt{\frac{\pi}{8}}(0.265\beta_n+1.194\beta_n^2+5.372\beta_n^{22}) \end{equation}

散射模型求解
#

头发表面的凸起角度α\alpha会影响θ\theta, pbrt估计RR偏移2α2\alpha, TTTT偏移α-\alpha, TRTTRT会偏移4α-4\alpha. 角度的偏移会导致高光瓣的偏移, 在头发上呈现出来的就是不同颜色的分层高光, 因为反射不影响颜色而折射会吸收光线.

可逆性
#

毛发BSDF是不可逆的, 这是由凸起方向以及ApA_p, NpN_p与折射方向相关导致的.

采样
#

首先以ApA_p作为概率分布采样pp, 然后分别采样MpM_pNpN_p, 这两项都可以实现精确采样.

毛发吸收系数
#

毛发的颜色由发皮质中的色素对光的吸收能力决定, 但毛发吸收系数与毛发颜色并不直接相关. 人类毛发中黑色素的浓度决定由金色到黑色的变化, 黄黑色素决定由橙色到红色的变化, pbrt中可以通过指定二者的浓度获取期望的发色.

PBRT_CPU_GPU RGBUnboundedSpectrum HairBxDF::SigmaAFromConcentration(Float ce, Float cp) {
    RGB eumelaninSigma_a(0.419f, 0.697f, 1.37f);
    RGB pheomelaninSigma_a(0.187f, 0.4f, 1.05f);
    RGB sigma_a = ce * eumelaninSigma_a + cp * pheomelaninSigma_a;
#ifdef PBRT_IS_GPU_CODE
    return RGBUnboundedSpectrum(*RGBColorSpace_sRGB, sigma_a);
#else
    return RGBUnboundedSpectrum(*RGBColorSpace::sRGB, sigma_a);
#endif
}