1. 程式人生 > >PBRT_V2 總結記錄 <38> Material 和 Intersection->GetBSDF

PBRT_V2 總結記錄 <38> Material 和 Intersection->GetBSDF

Material 類

class Material : public ReferenceCounted {
public:
    // Material Interface
    virtual BSDF *GetBSDF(const DifferentialGeometry &dgGeom,
                          const DifferentialGeometry &dgShading,
                          MemoryArena &arena) const = 0;
    virtual BSSRDF *GetBSSRDF(const DifferentialGeometry &dgGeom,
                              const DifferentialGeometry &dgShading,
                              MemoryArena &arena) const {
        return NULL;
    }
    virtual ~Material();
    static void Bump(const Reference<Texture<float> > &d, const DifferentialGeometry &dgGeom,
        const DifferentialGeometry &dgShading, DifferentialGeometry *dgBump);
};

類的作用:

(Material 是所有材質的基類,繼承Material的類要實現 Material::GetBSDF() 和 Material::GetBSSRDF(),這兩個方法主要負責確定 面上一個點 的反射屬性,並且返回這個點的BSDF或者BSSRDF)

The abstract Material class defines two methods that material implementations must provide, Material::GetBSDF() and Material::GetBSSRDF(). Implementations of these methods are responsible for determining the reflective properties at the given point on the surface and returning an instance of the BSDF class that describes them.

1. virtual BSDF *GetBSDF(const DifferentialGeometry &dgGeom,                           const DifferentialGeometry &dgShading,                           MemoryArena &arena) const = 0;

作用:

(dgGeom 表示的是 實際上 交點的幾何資訊,dgShading 表示的是,可能平滑過後的 交點的幾何資訊)

The Material::GetBSDF() method is given two differential geometry objects. The first, dgGeom, represents the actual differential geometry at the ray intersection point, and the second, dgShading, represents possibly perturbed(擾亂) shading geometry, such as that from per-vertex normals in a triangle mesh. The material implementation may further perturb(擾亂) the shading geometry with bump mapping in the GetBSDF() method; the returned BSDF holds information about the final shading geometry at the point as well as the BRDF and BTDF components for the point.

細節:

BSDF *GeometricPrimitive::GetBSDF(const DifferentialGeometry &dg,
                                  const Transform &ObjectToWorld,
                                  MemoryArena &arena) const {
    DifferentialGeometry dgs;
    shape->GetShadingGeometry(ObjectToWorld, dg, &dgs);
    return material->GetBSDF(dg, dgs, arena);
}

看 GeometricPrimitive 的GetBSDF方法,裡面是呼叫material的GetBSDF方法,在呼叫material的GetBSDF方法之前,會先進行shape->GetShadingGeometry方法,這個GetShadingGeometry方法在之前的《PBRT_V2 總結記錄 <7> Shape》中有提及,主要的作用就是:

通過DifferentialGeometry 可以得到更加平滑,更加準確的資料, 例如Triangle,在Intersect中計算得到的DifferentialGeometry的dpdu,dpdv, 其實就是自動計算的,但是,有時候Triangle 有可能自身提供了法線(dpdu)和切線(dpdv)的資料, 那麼GetShadingGeometry 就是 拋棄了自動計算的dpdu,dpdv,利用重心座標插值提供的法線和切線資料,重新生成 更加合適的 法線(dpdu),切線(dpdv)資料,參考 Triangle:GetShadingGeometry。

所以,material的GetBSDF方法中 dgShading 引數 就是 平滑過後的 dgGeom 。

2. virtual BSSRDF *GetBSSRDF(const DifferentialGeometry &dgGeom,                               const DifferentialGeometry &dgShading,                               MemoryArena &arena) const {         return NULL;     }

作用:

(BSSRDF 表示的是 透明材質,這個方法就是返回 一個BSSRDF,表示的就是物體 表面底下 散射屬性 )

For materials that represent translucent materials that exhibit subsurface(表面下的) scattering, theGetBSSRDF() method returns a BSSRDF object that represents the object’s subsurface scattering properties. The BSSRDF is defined later, in Section 11.6, after the foundations of volumetric scattering have been introduced. Because most materials don’t have meaningful amounts of subsurface scattering, this method has a default implementation that just returns NULL.

3. BSDF *Intersection::GetBSDF(const RayDifferential &ray, MemoryArena &arena) const

BSDF *Intersection::GetBSDF(const RayDifferential &ray,
                            MemoryArena &arena) const {
    PBRT_STARTED_BSDF_SHADING(const_cast<RayDifferential *>(&ray));
    dg.ComputeDifferentials(ray);
    BSDF *bsdf = primitive->GetBSDF(dg, ObjectToWorld, arena);
    PBRT_FINISHED_BSDF_SHADING(const_cast<RayDifferential *>(&ray), bsdf);
    return bsdf;
}

BSSRDF *Intersection::GetBSSRDF(const RayDifferential &ray,
          MemoryArena &arena) const {
    PBRT_STARTED_BSSRDF_SHADING(const_cast<RayDifferential *>(&ray));
    dg.ComputeDifferentials(ray);
    BSSRDF *bssrdf = primitive->GetBSSRDF(dg, ObjectToWorld, arena);
    PBRT_FINISHED_BSSRDF_SHADING(const_cast<RayDifferential *>(&ray), bssrdf);
    return bssrdf;
}

作用:

(常用的用法 是直接呼叫 Intersection->GetBSDF,Intersection->GetBSDF 中呼叫 Primitive->GetBSDF,Primitive->GetBSDF 中再去呼叫 Material->GetBSDF,對於 GetBSSRDF 已經一樣的道理,值得注意的是,在  Intersection->GetBSDF 呼叫了  Differentialgeometry::ComputeDifferentials() 方法,這個方法主要的作用就是: 計算 交點附近的面區域投影大小 資訊)

Since the usual interface to the hit point used by Integrators is through an instance of the Intersection class, we will add two convenience methods to Intersection, GetBSDF() and GetBSSRDF(), that respectively return the BSDF or BSSRDF at the hit point.

These methods call the Differentialgeometry::ComputeDifferentials() method to compute information about the projected size of the surface area around the intersection on the image plane for use in texture antialiasing and then forward the request to the Primitive, which in turn will call the corresponding GetBSDF() or GetBSSRDF() method of its Material.