PBRT_V2 总结记录 <28> Fresnel 和 FresnelConductor 和 FresnelDielectric 和 FresnelNoOp

Fresnel 类:

class Fresnel {
public:
    // Fresnel Interface
    virtual ~Fresnel();
    virtual Spectrum Evaluate(float cosi) const = 0;
};

类的作用:

(Fresnel  是 FresnelConductor 和  FresnelDielectric 的子类)

For convenience, we will define an abstract Fresnel class that provides an interface for
computing Fresnel reflection coefficients.
The FresnelConductor and FresnelDielectric
implementations of this interface help simplify the implementation of subsequent BRDFs
that may need to support both forms.

 

1. virtual Spectrum Evaluate(float cosi) const = 0;

The only method provided by the Fresnel interface is Fresnel::Evaluate(). Given the
cosine of the angle made by the incoming direction and the surface normal, it returns
the amount of light reflected by the surface.

 

 

FresnelConductor 类

class FresnelConductor : public Fresnel {
public:
    // FresnelConductor Public Methods
    Spectrum Evaluate(float cosi) const;
    FresnelConductor(const Spectrum &e, const Spectrum &kk)
        : eta(e), k(kk) {
    }

private:
    Spectrum eta, k;
};

类的作用:

(模拟导体的反射,导体只有reflectance,没有 transmitted)

 

1.  

Spectrum FresnelConductor::Evaluate(float cosi) const {
    return FrCond(fabsf(cosi), eta, k);
}
 

作用:

(直接调用 上一节的 FrCond 方法)

The evaluation routine for FresnelConductor is also simple; it just calls the FrCond()
function defined earlier. Note that it takes the absolute value of cosi before calling
FrCond(), since FrCond() expects that the cosine will be measured with respect to the
normal on the same side of the surface as ωi, or equivalently that the absolute value of
cos θi should be used.

 

FresnelDielectric 类

class FresnelDielectric : public Fresnel {
public:
    // FresnelDielectric Public Methods
    Spectrum Evaluate(float cosi) const;
    FresnelDielectric(float ei, float et) : eta_i(ei), eta_t(et) { }
private:
    float eta_i, eta_t;
};

类的作用:

(模拟绝缘体材质,有reflectanc 和 transmitted, transmitted = 1 - reflectanc)

FresnelDielectric similarly implements the Fresnel interface for dielectric materials

 

1. 


Spectrum FresnelDielectric::Evaluate(float cosi) const {
    // Compute Fresnel reflectance for dielectric
    cosi = Clamp(cosi, -1.f, 1.f);

    // Compute indices of refraction for dielectric
    bool entering = cosi > 0.;
    float ei = eta_i, et = eta_t;
    if (!entering)
        swap(ei, et);

    // Compute _sint_ using Snell's law
    float sint = ei/et * sqrtf(max(0.f, 1.f - cosi*cosi));
    if (sint >= 1.) {
        // Handle total internal reflection
        return 1.;
    }
    else {
        float cost = sqrtf(max(0.f, 1.f - sint*sint));
        return FrDiel(fabsf(cosi), cost, ei, et);
    }
}

细节:

a.

(先判断入射向量是 是否与 法线在同一个半球,如果不是的话,就要 交换 折射的两个 indices,利用 Snell's Law 来计算出

sin θt, 再计算出 cos θt,得到 FrDiel 方法需要的所有参数)

Evaluating the Fresnel formula for dielectric media is a bit more complicated than for
conductors. First, it is necessary to determine if the incident direction is on the outside
of the medium or inside it, so that the two indices of refraction can be interpreted(解析)
appropriately.
Next, Snell’s law is applied to compute the sine of the angle between the
transmitted direction and the surface normal.
Finally, the cosine of this angle is found
using the identity sinθ^2 + cos θ^2 = 1.

 

b.

bool entering = cosi > 0.;
float ei = eta_i, et = eta_t;
if (!entering)
    swap(ei, et);

作用:

(判断入射向量是 是否与 法线在同一个半球,如果不是的话,就要 交换 折射的两个 indices)

The sign of the cosine of the incident angle indicates on which side of the medium the
incident ray lies (Figure 8.6). If the cosine is between 0 and 1, the ray is on the outside,
and if the cosine is between −1 and 0, the ray is on the inside. The variables ei and et are
set such that ei has the index of refraction of the incident medium.

 

c.

float sint = ei/et * sqrtf(max(0.f, 1.f - cosi*cosi));

作用:

(利用 Snell's Law 来计算出 sin θt)

Once the indices of refraction are set, we can compute sin θt using Snell’s law:

 

d.

if (sint >= 1.)
    // Handle total internal reflection
    return 1.;
}

作用:

(如果 sint 大于1 表示,全部反射 )

When light is traveling from one medium to another medium with a lower index of
refraction, none of the light at incident angles near grazing(擦边) passes into the other medium.

The largest angle at which this happens is called the critical angle; when θi is greater than
the critical angle, total internal reflection occurs, and all of the light is reflected.
That case
is detected here by a value of sin θt greater than one; in that case, the Fresnel equations
are unnecessary.

 

FresnelNoOp 类:

class FresnelNoOp : public Fresnel {
public:
    Spectrum Evaluate(float) const { return Spectrum(1.); }
};

类的作用:

(100% 反射)

The FresnelNoOp implementation of the Fresnel interface returns 100% reflection for all
incoming directions.
Although this is physically implausible, it is a convenient capability
to have available

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值