BSDF类

表面着色器会绑定场景中每一个图元(被赋予了这个着色器),而表面着色器则由Material类的实例来表示。它会拥有一个BSDF类对象(可能是BSSDF),用于计算表面上每一点的辐射度(颜色)。

BSDF代表了BRDFs与BTDFs的集合。BSDF构造函数接受一个SurfaceInteraction对象,该对象包含关于表面上任意一点的微分几何信息,以及一个参数eta,该参数给出了边界上的相对折射率。对于不透明的表面,该参数则无效。构造函数将使用着色法线来构造一个正交坐标系。本节中ns表示着色法线(法线贴图上对应坐标的值)和ng代表了几何法线(面法线)。

BSDF存储了最多8个BxDF组件,因为在pbrt中不需要更多组件。BSDF实现了BxDFs坐标系与世界坐标系转换的方法。WorldToLocal(const Vector3f &v)与LocalToWorld(const Vector3f &v)。

着色法线与几何法线的冲突问题

实际渲染的过程中着色法线可能会发生如图9.2这样的漏光现象情况,也就是说直接计算出得到错误的光线遮挡关系。解决方法是:使用几何法线来决定是计算反射还是计算透射,如果ωi与ωo在同一个几何法线的半球,计算BRDFs,不然则计算BTDFs。与上一步不同,在计算散射方程时,法线和入射方向的点积仍然是用着色法线而不是几何法线来处理的。

首先将向量从世界坐标系转换为BSDF坐标系,然后决定是使用BRDFs还是BTDFs。然后循环遍历适当的集合并计算它们的辐射度贡献之和。

Spectrum BSDF::f(const Vector3f &woW, const Vector3f &wiW,
BxDFType flags) const {
ProfilePhase pp(Prof::BSDFEvaluation);
Vector3f wi = WorldToLocal(wiW), wo = WorldToLocal(woW);
if (wo.z == 0) return 0.;
bool reflect = Dot(wiW, ng) * Dot(woW, ng) > 0;
Spectrum f(0.f);
for (int i = 0; i < nBxDFs; ++i)
if (bxdfs[i]->MatchesFlags(flags) &&
((reflect && (bxdfs[i]->type & BSDF_REFLECTION)) ||
(!reflect && (bxdfs[i]->type & BSDF_TRANSMISSION))))
f += bxdfs[i]->f(wo, wi);
return f;
}

Material类

Material的派生类必须实现ComputeScatteringFunctions();该函数获取一个SurfaceInteraction对象,该方法用于确定反射属性,并且初始化相应的SurfaceInteraction::BSDF,如果包含了次表面散射,那SurfaceInteraction::BSSRDF也会被初始化。另外几个形参别分是:所使用的内存池引用,透射模式,是否使用多层复合材质的BxDFs(类似车漆这种),之后SurfaceInteraction的实例会调用这个函数进行渲染。

void SurfaceInteraction::ComputeScatteringFunctions(const RayDifferential &ray,MemoryArena &arena,bool allowMultipleLobes,TransportMode mode) {
ComputeDifferentials(ray);
primitive->ComputeScatteringFunctions(this, arena, mode,
allowMultipleLobes);
}

金属材质

kd为漫反射值,sigma为粗糙度值。如果sigma为0,即为兰伯特材质,不然就使用OrenNayar模型,另外还有一个凹凸贴图指针变量,在其有效的情况下,用与着色法线的计算。

void MatteMaterial::ComputeScatteringFunctions(SurfaceInteraction *si,MemoryArena &arena,TransportMode mode,bool allowMultipleLobes) const {
if (bumpMap) Bump(bumpMap, si); si->bsdf = ARENA_ALLOC(arena, BSDF)(*si);
Spectrum r = Kd->Evaluate(*si).Clamp();
Float sig = Clamp(sigma->Evaluate(*si), 0, 90);
if (!r.IsBlack()) {
if (sig == 0)
si->bsdf->Add(ARENA_ALLOC(arena, LambertianReflection)(r));
else
si->bsdf->Add(ARENA_ALLOC(arena, OrenNayar)(r, sig));
}
}

塑料材质

塑料可以被建模为漫反射和光泽散射函数的混合物,参数控制特定的颜色和高光尺寸。塑料材质的参数为Kd和Ks,分别控制漫反射和高光的量。

reaproughness为控制粗糙度效果的变量,如果remapRoughness参数为true,那么roughness将会映射到0~1范围,其中粗糙度值越高,高光亮点越大。如果为false,那么粗糙度直接初始化microfacet分布的参数α(8.4.2的内容)

void PlasticMaterial::ComputeScatteringFunctions(
SurfaceInteraction *si, MemoryArena &arena, TransportMode mode,
bool allowMultipleLobes) const {
// Perform bump mapping with _bumpMap_, if present
if (bumpMap) Bump(bumpMap, si);
si->bsdf = ARENA_ALLOC(arena, BSDF)(*si);
// Initialize diffuse component of plastic material
Spectrum kd = Kd->Evaluate(*si).Clamp();
if (!kd.IsBlack())
si->bsdf->Add(ARENA_ALLOC(arena, LambertianReflection)(kd)); // Initialize specular component of plastic material
Spectrum ks = Ks->Evaluate(*si).Clamp();
if (!ks.IsBlack()) {
Fresnel *fresnel = ARENA_ALLOC(arena, FresnelDielectric)(1.5f, 1.f);
// Create microfacet distribution _distrib_ for plastic material
Float rough = roughness->Evaluate(*si);
if (remapRoughness)
rough = TrowbridgeReitzDistribution::RoughnessToAlpha(rough);
MicrofacetDistribution *distrib =
ARENA_ALLOC(arena, TrowbridgeReitzDistribution)(rough, rough);
BxDF *spec =
ARENA_ALLOC(arena, MicrofacetReflection)(ks, distrib, fresnel);
si->bsdf->Add(spec);
}
}

混和材质

存储了2个材质的指针,以及一个缩放参数。

void MixMaterial::ComputeScatteringFunctions(SurfaceInteraction *si,MemoryArena &arena,TransportMode mode,bool allowMultipleLobes) const {
// Compute weights and original _BxDF_s for mix material
Spectrum s1 = scale->Evaluate(*si).Clamp();
Spectrum s2 = (Spectrum(1.f) - s1).Clamp();
SurfaceInteraction si2 = *si;
m1->ComputeScatteringFunctions(si, arena, mode, allowMultipleLobes);
m2->ComputeScatteringFunctions(&si2, arena, mode, allowMultipleLobes); // Initialize _si->bsdf_ with weighted mixture of _BxDF_s
int n1 = si->bsdf->NumComponents(), n2 = si2.bsdf->NumComponents();
for (int i = 0; i < n1; ++i)
si->bsdf->bxdfs[i] =
ARENA_ALLOC(arena, ScaledBxDF)(si->bsdf->bxdfs[i], s1);
for (int i = 0; i < n2; ++i)
si->bsdf->Add(ARENA_ALLOC(arena, ScaledBxDF)(si2.bsdf->bxdfs[i], s2));
}

除此之外的材质

PBRT还实现了一些别的材质,其实现代码都在materials目录中。

  1. GlassMaterial
  2. MetalMaterial
  3. MirrorMaterial
  4. SubsurfaceMaterial
  5. TranslucentMaterial
  6. UberMaterial

PBRT笔记(8)——材质的更多相关文章

  1. PBRT笔记(14)——光线传播2:体积渲染

    传输公式 传输方程是控制光线在吸收.发射和散射辐射的介质中的行为的基本方程.它解释了第11章中描述的所有体积散射过程--吸收.发射和内.外散射.并给出了一个描述环境中辐射分布的方程.光传输方程实际上是 ...

  2. PBRT笔记(10)——体积散射

    体散射处理过程 3个影响参与介质在环境中的辐射度分布的主要因素: 吸收:减少光能,并将其转化为别的能量,例如热量. 发光:由光子发射光能至环境中. 散射:由于粒子碰撞,使得一个方向的辐射度散射至其他方 ...

  3. PBRT笔记(7)——反射模型

    基础术语 表面反射可以分为4大类: diffuse 漫反射 glossy specular 镜面反射高光 perfect specular 完美反射高光 retro-reflective distri ...

  4. PBRT笔记(6)——采样和重构

    前言 本文仅作为个人笔记分享,又因为本章涉及多个专业领域而本人皆未接触过,所以难免出错,请各位读者注意. 对于数字图像需要区分image pixels(特定采样处的函数值)和display pixel ...

  5. [Unreal]学习笔记之材质说明

    取消蓝图中的连接线:Alt+鼠标左键 在蓝图中,通过按住1,2,3,4加鼠标左键,可以快速生成1,2,3,4维的向量 材质和材质实例的区别:使用一个母材质,可以创建出多种场景中的材质实例:每次修改母材 ...

  6. PBRT笔记(13)——光线传播1:表面反射

    采样反射函数 BxDF::Sample_f()方法根据与相应的散射函数相似的分布来选择方向.在8.2节中,该方法用于寻找来自完美镜面的反射和透射光线;在这里讲介绍实现其他类型的采样技术. BxDF:: ...

  7. PBRT笔记(12)——蒙特卡洛积分

    这里还涉及到pdf.方差等概念,推荐去看<全局光照技术:从离线到实时渲染> 积累分布函数 cumulative distribution function (CDF) 蒙特卡洛估算 为了计 ...

  8. PBRT笔记(11)——光源

    自发光灯光 至今为止,人们发明了很多光源,现在被广泛使用的有: 白炽灯的钨丝很小.电流通过灯丝时,使得灯丝升温,从而使灯丝发出电磁波,其波长的分布取决于灯丝的温度.但大部分能量都被转化为热能而不是光能 ...

  9. PBRT笔记(9)——贴图

    采样与抗锯齿 当高分辨率贴图被缩小时,贴图会出现严重的混淆现象.虽然第7章中的非均匀采样技术可以减少这种混叠的视觉影响,但是更好的解决方案是实现基于分辨率进行采样的纹理函数. 可以在使用贴图时先对贴图 ...

随机推荐

  1. @JoinColumn解释

    @JoinColumn与@Column标记一样,是用于注释表中的字段的.它的属性与@Column属性有很多相同之处,这里就不详细讲述.请读者参阅5.2.2小节中有关@Column属性的部分. l    ...

  2. nautilus-open-terminal----在当前目录下打开终端

    nautilus-open-terminal很有用的插件--鼠标右键打开终端 1.1 fedora安装 # yum -y install nautilus-open-terminal安装nautilu ...

  3. AIC与BIC

    首先看几个问题 1.实现参数的稀疏有什么好处? 一个好处是可以简化模型.避免过拟合.因为一个模型中真正重要的参数可能并不多,如果考虑所有的参数作用,会引发过拟合.并且参数少了模型的解释能力会变强. 2 ...

  4. jmeter使用csv传参进行并发测试验证

    1.获取到注册接口,添加HTTP信息头管理器.HTTP请求,设置好入参,且检查使用csv文件传参的入参 2.创建csv文件,写入需要传的入参 3.添加CSV Data Set Config 设置配置 ...

  5. 浅入深出Vue系列

    浅入深出Vue导航 导航帖,直接点击标题即可. 文中所有涉及到的资源链接均在最下方列举出来了. 前言 基础篇 浅入深出Vue:工具准备之WebStorm搭建及配置 浅入深出Vue之工具准备(二):Po ...

  6. 前端DES加密

    /** * DES加密/解密 * @Copyright Copyright (c) 2018 * @author mrDu * @see DESCore */ /* * encrypt the str ...

  7. rootkit后门检测工具

    1. 关于rootkit rootkit是Linux平台下最常见的一种木马后门工具,它主要通过替换系统文件来达到入侵和和隐蔽的目的,这种木马比普通木马后门更加危险和隐蔽,普通的检测工具和检查手段很难发 ...

  8. [精品书单]3D打印机课程设计

    3D打印机整个绘图过程........... 三维图 工程图 编程

  9. 论文翻译:Neural Networks With Few Multiplications

    目录 Abstract 1. Introduction 2.Related Work 3.Binary And Ternary Connect 3.1 BINARY CONNECT REVISITED ...

  10. 强大的Resharp插件(转)

    使用VS有段时间了,一直深深的折服于其强大的功能.之前一直听说有Resharp这个工具,小猪一直也没有太在意.直到今天…… 下载安装: http://www.jetbrains.com/resharp ...