UnityShader入门精要C18-基于物理的渲染

本文记录《UnityShader入门精要》第18章的读书笔记。

*第18章介绍了 Unity 中的基于物理的渲染 PBS。首先介绍了理论基础和数学基础,光是什么,是如何在物体表面发生交互的:一部分光会反射回来,形成高光反射;另一部分会被物体吸收或者次表面散射,形成漫反射项。然后介绍了 Standard Shader,这是 Unity 实现的默认的基于物理的渲染的 Shader。*

基于物理的渲染,是对现实中关照效果的一种抽象总结,并不是还原现实,只是可以用一个 Shader,渲染很多类型的材质。

18. 基于物理的渲染

基于物理的渲染技术(Physically Based Shading, PBS)。总体来说,PBS 是为了对光和材质之间的行为进行更加真实的建模。PBS 实现比较复杂,而且不意味着渲染出来的画面一定是像照片一样真实的。

Unity5 引入的基于物理的渲染不需要我们过多的了解 PBS 是如何实现的,就能利用各种内置工具来实现一个不错的渲染效果。

18.1 PBS 的理论和数学基础

本节主要参考 Naty Hoffman 在 SIGGRAPH 2013 上做的名为 Background: Physics and Math of Shading 的演讲。

18.1.1 光是什么

光由太阳或其他光源中发射出来,然后与场景中的对象相交,一些光线被吸收(absorption),而另一些则被散射(scattering),最后光线被一个感应器(例如我们的眼睛)吸收成像。

折射率(refractive index),如果光在传播时介质的折射率发生了变化,光的传播方向就会发生变化。如果折射率是突变的,就会发生光的散射现象。

假想的理想情况下,光在不同介质的边界会被分割成两个方向:反射方向和折射方向。有多少百分比的光会被反射(另一部分被折射)是由菲涅尔等式(Fresnel equations)来描述的:

然而,物体表面并不是真的绝对平滑,而是有很多凹凸不平的小平面。有些物体,微表面法线方向变化角度小,因此这些表面反射的光线方向变化小,高光反射清晰。有些物体,表面更粗糙,高光反射模糊:

被折射的光,会进入物体内部,一部分被吸收,一部分又被散射到外部。金属材质具有很高的吸收系数,因此所有被折射的光会被立刻吸收。非金属材质会同时表现出吸收和散射两种现象,这些被散射出去的光被称为次表面散射光(subsurface-scattered light)

根据相机距离物体的远近,需要使用的渲染技术不同。如果距离近,就不能忽略次表面散射效果;如果远,就不用考虑次表面。

18.1.2 双向反射分布函数(BRDF)

现在使用数学表达式来表示,对光这个看似抽象的概念进行量化。

辐射率(radiance)来量化光:辐射率是单位面积、单位方向上光源的辐射通量 L。着色(shading)过程:基于表面的入射光线和入射辐射率 Li 来计算出射辐射率 Lo。

为了得到出射辐射率 Lo,需要使用 BRDF(Bidirectional Reflectance Distribution Function,双向反射分布函数)来定量分析。BRDF 可以用 f(l,v) 来表示,l 为入射方向,v 为观察方向(双向的含义):

  • 各向同性(isotropic):绕着表面法线旋转入射方向或观察方向,不影响 BRDF 的结果
  • 各项异性(anisotropic):会影响 BRDF 的结果

BRDF 有两种理解方式:

  1. 第一种理解是,给定入射角度后,BRDF 可以给出所有出射方向上的反射和散射光线的相对分布情况。
  2. 第二种理解是,给定观察方向后(即出射方向),BRDF 可以给出所有入射方向到该出射方向的光线分布。
  3. 一个更直观的理解是,当一束光线沿着入射方向 l 到达表面某点时,f(l,v)表示了有多少部分的能量被反射到了观察方向 v 上。

反射等式(reflection equation)

反射等式的理解:把不同方向的光辐射率(Li(l)部分)乘以观察方向上所占的权重(f(l,v)部分),再乘以它们在该表面的投影结果(n·l部分),最后再把这些值加起来(做积分)。这就是最后的出射辐射率。

在游戏渲染中,我们通常和精确光源(punctual light sources)打交道,而不是计算所有入射光线在半球面上的积分。精确光源指的是那些方向确定、大小为无限小的光源,例如常见的点光源、聚光灯等。我们使用Lc来表示他的方向,使用Clight表示他的颜色。对于一个精确光源,我们可以使用下面的等式来计算他在某个观察方向v上的出射辐射率:

与之前使用的积分形式的原始反射等式相比,上面的式子使用一个特定的 BRDF 值来代替积分操作,这大大简化了计算。

那么 BRDF 是如何得到的?BRDF 决定着色过程是否是基于物理的。他有两个特性,交换律(reciprocity)能量守恒(energy conservation)

交换律要求当交换 l 和 v 的值后,BRDF 的值不变,即:

能量守恒则要求表面反射的能量不能超过入射的光能,即:

基于这些理论,BRDF 可以用于描述两种不同的物理现象:表面反射和次表面散射:

  • 高光反射项(specular term):用于描述表面反射的部分
  • 漫反射项(diffuse term):用于描述次表面散射的部分

18.1.3 漫反射项

我们之前所学习的 Lambert 模型就是最简单、也是应用最广泛的漫反射 BRDF。准确的 Lambertian BRDF 的表示为:

因此给定入射方向 l 的光源,在表面某点的出射漫反射辐射率为:

很多基于物理的渲染选择使用了更复杂的漫反射项来模拟次表面散射的效果,例如 Disney 使用的 BRDF 中,它的漫反射项为:

上面的式子也是 Unity5 内部使用的漫反射项。

18.1.4 高光反射项

在现实生活中,几乎所有的物体都或多或少的有高光反射现象,Everything is Shiny。在基于物理的渲染中,BDRF 中的高光反射项大多数都是建立在微面元理论(microfacet theory)的假设上的。

微面元理论认为,物体表面实际是由许多人眼看不到的微面元组成的。虽然物体表面并不是光学平滑的,但这些微面元可以被认为是光学平滑的,也就是说他们具有完美的高光反射。当然微面元理论也仅仅是真实世界的散射的一种近似理论。

假设表面法线为 n,这些微面元的法线 m 并不都等于 n。给定入射方向 l 和观察方向 v,只有一部分微面元反射的光线才会进入到我们的眼睛中,这部分微面元会恰好把光线反射到方向 v 上,即他们的法线 m 等于 l 和 v 的一半,也就是我们一直看到的半角度矢量 h(half-angle vector,也被称为 half vector)。

这些 m = h 的微面元也并不会全部添加到 BRDF 的计算中。因为他们其中一部分会在入射方向 l 上被其他微面元挡住(shadowing),或是在他们的反射方向 v 上被其他微面元挡住了(masking)。

基于微面元理论的这些假设,BRDF 的高光反射项可以用下面的形式来表示,这就是著名的 Torrance-Sparrow 微面元模型:

上面的式子,各个项对应了我们之前讲到的不同现象:

  • D(h):法线分布函数(normal distribution function, NDF)。用于计算有多少比例的微面元的法线满足 m = h。
  • G(l,v,h):阴影-遮掩函数(shadowing-masking function)。用于计算那些满足 m = h 的微面元中有多少会由于遮挡,而不会被人眼看到。
  • F(l,h):菲涅尔反射函数(Fresnel reflectance),可以告诉我们每个活跃的微面元会把多少入射光线反射到观察方向上,即表示了反射光线占入射光线的比率。
  • 分母 4(nl)(nv):用于校正微面元的局部空间到整体宏观表面数量差异的校正因子。

这些不同的部分又可以衍生出很多不同的 BRDF 实现,例如我们之前学习的 Blinn-Phong 模型就是一种非常简单的模型,他使用的法线分布函数 D(h) 为:

有更加复杂的分布函数,例如 GGX、Beckmann,以及阴影-遮掩函数,例如 Smith 模型。这些数学模型都是为了更加接近使用光学测量仪器测量出来的真实物体的反射分布数据。

18.1.5 Unity 中的 PBS 实现

可以在 Unity 内置的 UnityStandardBRDF.cginc 文件中找到 Unity5 的 PBS 实现。总体来说,一共实现了两种 PBS 模型,一种是基于 GGX 模型的,另一种则是基于归一化的 Blinn-Phong 模型的。(Unity5.3 及以后的版本,默认将使用 GGX 模型,和很多其他主流引擎的选择一致)

Unity 使用的 BRDF 中的漫反射项公式如上文 Disney 的。

下面给出基于 GGX 模型的高光反射项公式,对于基于归一化的 Blinn-Phong 模型的高光反射公式,可以在 UnityStandardBRDF.cginc 中找到。

GGX 模型的法线分布函数 D(h):

阴影-遮掩函数 G(l,v,h) 则使用了一种由 GGX 衍生出的 Smith-Schlick 模型:

菲涅尔反射 F(l,h) 则使用了图形学中经常使用的 Schlick 菲涅尔近似等式:

幸运的是,在 Unity 中我们不需要自己在 Shader 中实现上面的公式,Unity 已经为我们提供了现成的基于物理着色的 Shader,也就是 Standard Shader

18.2 Unity 5 的 Standard Shader

当我们在 Unity 5 中新创建一个模型或是材质时,其默认使用的着色器都是一个名为 Standard 的着色器。

Unity 支持两种流行的基于物理的工作流程:

  • 金属工作流(Metallic workflow):对应的 Shader 为 Standard Shader
  • 高光反射工作流(Specular workflow):对应的 Shader 为 Standard (Specular setup)

以上两种工作流,可以实现相同的效果,只是他们使用的参数不同。Unity 提供的 Standard Shader 允许让我们只使用这一种 Shader 来为场景中所有物体进行着色,而不需要考虑他们是否是金属材质还是塑料材质。

18.2.1 他们是如何实现的

源码可以在 Unity 内置的 builtin_shaders-x/DefaultResourcesExtra 文件夹中找到。这些 Shader 依赖于 builtin_shaders-x/CGIncludes 中定义的 UnityStandardXXX.cginc 头文件,他们定义了和 PBS 相关的各个函数、结构体和宏等(我简写了,详请参阅原书):

  • UnityPBSLighting.cginc:定义了标准光照函数和相关的结构体等,如 LightingStandardSpecular 函数和 SurfaceOutputStandardSpecular 结构体
  • UnityStandardCore.cginc:定义了 Standard 和 Standard (Specular setup) Shader 使用的顶点/片元着色器和相关的结构体、辅助函数等,如 vertForwardBase 函数和 VertexOutputForwardBase 结构体
  • UnityStandardBRDF.cginc:实现了 Unity 中基于物理的渲染技术,定义了实现不同平台下 BRDF 的函数
  • UnityStandardInput.cginc:声明了 Standard Shader 使用的相关输入,定义了基于这些输入的辅助函数,如 Albedo 等
  • UnityStandardUtils.cginc:一些辅助函数,将来可能会移动到 UnityCG.cginc 中
  • UnityStandardConfig.cginc:相关配置,例如默认情况下关闭简化版的 PBS 实现
  • UnityStandardMeta.cginc:定义了 LightMode 为 Meta 的 Pass 使用的顶点/片元着色器,以及他们使用的输入/输出结构体(用于提取光照纹理和全局光照的相关信息)
  • UnityStandardShadow.cginc:定义了 LightMode 为 ShadowCaster 的 Pass 使用的顶点/片元着色器,以及他们使用的输入/输出结构体(用于投射阴影)
  • UnityGlobalIllumination.cginc:定义了和全局光照相关的函数,如 UnityGlobalIllumination 函数

总体来讲 Standard.shader 和 StandardSpecular.shader 代码基本相同——都定义了两个 SubShader:第一个 SubShader 针对非移动平台,第二个 SubShader 针对移动平台。

Standard.shader 和 StandardSpecular.shader 最大的不同之处在于,使用了不同的函数来设置参数:MetallicSetup 和 SpecularSetup 函数,均在 UnityStandardCore.cginc 中被定义。

下图比较了 Standard Shader 中前向渲染路径使用的 Pass:

18.2.2 如何使用 Standard Shader

我们应该如何使用 Standard Shader 来得到不同的材质效果呢?

通过对金属材质和非金属材质的分析,我们可以得到他们的漫反射和高光反射的一些特点:

  • 金属材质:
    • 几乎没有漫反射。因为所有被吸收的光都会被自由电子立刻转化为其他形式的能量;
    • 有非常强烈的高光反射;
    • 高光反射通常是有颜色的,例如金子的反光颜色为黄色
  • 非金属材质:
    • 大多数高光反射的强度比较弱,但在掠射角时高光反射强度反而会增强,即菲涅尔现象;
    • 高光反射的颜色比较单一;
    • 漫反射的颜色多种多样。

但真实的材质大多混合了上面的这些特性。Unity 提供了两个非常有参考价值的标准表格,他们分别对用了金属工作流和高光反射工作流使用的参考属性值:


如何使用这个标准表格呢?下面使用金属工作流来实现

  1. 设置颜色空间:在 Edit -> Project Settings -> Player -> Other Settings -> Color Space 中选择 Linear (线性颜色空间)
  2. Albedo (RGB):
    1. Non-Metal:sRGB Range 50~243
    2. Metal:sRGB Range 186~255
    3. 看起来金属的 Albedo 比非金属要亮
  3. Metallic (R):
    1. Almost all Non-Metals = 0.0
    2. Almost all Metals = 1.0
  4. Smoothness (A):根据实际需求来设定,值 0.0~1.0,越大越光滑

参考这个表格,设置的参数和实现的效果如下(注意需要点击 Unity Editor 的右下角,开启 Auto Generate Lighting,或者在打开的对话框中手动构建光照。否则金属物体表面可能没有任何反射效果!):

高光反射工作流使用的面板和上述金属工作流使用的基本相同,只是使用了不同含义的 Albedo 属性,并使用 Specular 代替了上述的 Metallic 属性。

除了材质面板中的 Main Maps 部分,还有其他可以设置的:

  • 切线空间下的法线纹理
  • 遮挡纹理
  • 自发光纹理等
  • 额外的细节信息 Secondary Maps
  • 渲染模式 Render Mode
    • Opaque:不透明物体。默认的渲染模式
    • Cutout:透明度测试
    • Fade:半透明。类似 Transparent,该材质的所有渲染效果都会逐渐从屏幕上淡出
    • Transparent:半透明。当材质的透明度不断降低时,它的反射依然能被保留

尽管 Standard Shader 的材质面板有许多可供调节的属性,但我们不用担心由于没有使用一些属性而会对性能有所影响。Unity 在背后已经进行了高度优化,会检查哪些属性没有被使用到。

还有其他一些重要的技术,使场景的渲染结果更令人满意,例如:

  • HDR 格式的 Skybox
  • 全局光照
  • 反射探针
  • 光照探针
  • HDR 和屏幕后处理等

18.3 一个更加复杂的例子

首先将颜色空间设置为线性,因为基于物理的渲染需要使用线性空间:Edit -> Project Settings -> Player -> Other Settings -> Color Space 中选择 Linear

18.3.1 设置光照环境

使用作者提供的 SunsetSkyboxHDR,制作一个天空球材质。新增材质,Shader 选择 Skybox/Panoramic,这个 Shader 可以使用一个 HDR(全景图片)作为纹理。将这个材质设置给 LightingSettings 的 Skybox。

还可以设置场景使用的环境光照

  • 环境光照来源 Ambient Source
    • 来自于场景使用的 Skybox
    • 还是渐变值
    • 固定的颜色
  • 环境光照的强度 Ambient Intensity

在使用了 Standard Shader 的前提下,即使我们关闭场景中所有的光照,并把环境光照的强度设为0,场景中的物体仍然可以接受一些光照。这是由于反射

默认的反射源(Reflection Source)是场景使用的 Skybox。如果我们不想让场景中的物体接受任何默认的光照,可以把反射源设置为自定义(Custom),并把自定义的 Cubemap 保留为空(另一种方式是直接把场景使用的 Skybox 设置为空)。


除了 Standard Shader 外,Unity 还引入了一个重要的流水线——实时全局光照(Global Illumination, GI)流水线。使用 GI,场景中的物体不仅可以受直接光照的影响,还可以接受间接光照的影响。

直接光照使用一个平行光。

在平行光的烘焙选项(Baking)中,我们选择了 Realtime 模式,这意味着场景中受平行光影响的所有物体都会进行实时的光照计算。

间接光照是直接光照在各个物体之间来回反射产生的。Bounce Intensity可以让我们调节这些间接光照的强度,值为0表示一条光线仅会和一个物体相交,不再继续反射。(这个设置在 Unity2019 中似乎没有了

18.3.2 放置反射探针

反射探针(Reflection Probes),允许我们在场景中的特定位置上对整个场景的环境反射进行采样,并把采样结果存储在每个探针上。如果物体周围存在多个反射探针,Unity 还会在这些反射结果之间进行插值,来得到平滑渐变的反射效果。

反射探针也有 Baked/Realtime/Custom 三种类型。

放置反射探针时的位置并不是任意的,通常应该放置在那些具有明显反射现象的物体旁边,或是一些墙角等容易发生遮挡的物体周围。例如本例中,可以放在盾牌附近。

反射探针还可以模拟互相反射(interreflections)

没放置反射探针(左)和放了反射探针(右)的效果如下:

18.3.3 调整材质

基于物理的渲染并不意味着一定要模拟向照片真实的效果,而是我们的场景在各种光照条件下都能得到令人满意的效果,而不用频繁的调整参数。

这里的场景中所有物体都使用了高光反射纹理(Specular Texture)、遮挡纹理(Occlusion Textuer)、法线纹理(Normal Texture),一些材质还使用了细节纹理来提供更多的细节表现。

18.3.4 线性空间

使用基于物理的渲染方法渲染整个场景时,我们应该使用线性空间(Linear Space)来得到最好的渲染结果。而默认情况下,Unity 会使用伽马空间(Gamma Space)。

线性空间可以得到更加真实的效果,但他的缺点在于需要一些硬件支持来实现线性计算。一些移动平台对他的支持并不好,这时只能使用伽马空间。

线性空间(左)和伽马空间(右)的对比:

线性空间、伽马空间到底是什么意思?这和伽马矫正(Gamma Correction)相关。我们在默认的伽马空间下进行渲染计算时,由于使用了非线性的输入数据,导致很多计算都是在非线性空间下进行的,这意味着我们得到的结果并不符合真实的物理期望。

18.4 答疑解惑

18.4.1 什么是全局光照

全局光照,指的就是模拟光线是如何在场景中传播的,他不仅会考虑那些直接光照的结果,还会计算光线被不同的物体表面反射而产生的间接光照。

Unity 采用了 Enlighten 解决方案来让全局光照在各种平台上有不错的性能表现。实时 + 预计算。

预计算光照包含了我们常见的光照烘焙,也就是把光源对场景中静态物体的光照效果提前烘焙到一张光照纹理中,然后把他直接贴在这些物体的表面。光照纹理无法在游戏运行时不断更新,所以他们是静态的。

为了能动态的给场景实时更新复杂的光照结果,Unity 使用了预计算实时全局光照(Precomputed Realtime GI)。

如何实现的?:

  • 物体和光源的位置被固定了,这些物体对于光线的反弹路径以及漫反射光照也是固定的。
  • 至少需要把场景中的一个物体标识为 Static(需要勾选 Lightmap Static)
  • 高光反射,是和相机位置相关的,Unity 的解决方案是使用反射探针

18.4.2 什么是伽马校正

把伽马空间转换到线性空间,就需要进行伽马校正(Gamma Correction)

伽马一词来源于伽马曲线,伽马曲线的表达式如下,其中指数部分的发音就是伽马:

最开始的时候,人们使用伽马曲线对拍摄的图像进行伽马编码(gamma encoding)。这是因为人眼有一个有趣的特性,对光的灵敏度在不同亮度上是不一样的:在正常的光照条件下,人眼对较暗区域的变化更加敏感。

这样如果使用8位空间来存储每个通道的话,我们依然把0.5亮度编码成值为0.5的像素,亮部和暗部都使用128种颜色表示,实际上对亮部区域使用这么多颜色是种浪费。所以应该把更多的空间来存储暗部。例如会使用大约为0.45的伽马编码输入的亮度,这时0.5像素值对应的亮度不是0.5,而是大约0.22,这是因为:

0.5 ≈ 0.22 ^ 0.45

当把图片放在显示器里显示时,应该对图像进行解码,使屏幕输出的亮度和捕捉到的亮度符合线性。然而人们发现了一个奇妙的巧合——CRT 显示器本身几乎已经自动做了解码操作!CRT(Cathode Ray Tube,阴极射线管)有个特性,他的输入电压和显示出来的亮度关系不是线性的,我们把显示器的这个伽马曲线称为显示伽马(display gamma)。非常巧合的是,显示伽马值大约就是编码伽马的倒数,正好补偿了图像捕捉设备的伽马曲线。

微软联合爱普生、惠普提供了 sRGB 颜色空间标准:推荐显示器的显示伽马值为2.2,并配合0.45的编码伽马,就可以保证最后伽马曲线之间可以相互抵消(因为 2.2 x 0.45 ≈ 1)。

对于输出来说,如果我们直接输出渲染结果而不进行任何处理,经过显示器的显示伽马处理后,会导致图像整体偏暗,出现失真的情况:

  • 对光照效果的影响:伽马空间下的渲染结果整体偏暗,线性空间会进行伽马校正,来抵消屏幕显示伽马的作用
  • 对混合造成影响:边界处有不正常的渐变,这是因为在混合后进行输出时,显示器的显示伽马导致接缝处颜色变暗

实际上,渲染中非线性输入最有可能的来源就是纹理。为了充分利用存储空间,大多数图像文件都进行提前的校正,即已经使用了一个编码伽马对像素值编码。

如上所说,伽马的存在使得我们很容易得到非线性空间下的渲染结果。在游戏渲染中,我们应该保证所有的输入都被转换到了线性空间下。Unity 的颜色空间设置就可以满足我们的需求:

  • 选择伽马空间:实际上就是“放任模式”,不会做啥处理,通常表现为整个场景比较昏暗
  • 选择线性空间:Unity 会把输入纹理设置为 sRGB 模式,会进行伽马校正

然而移动平台无法使用线性空间,此时我们就需要自己在 Shader 中进行伽马校正,例如:

// 处理非线性输入纹理的校正代码
float3 diffuseCol = pow(tex2D(diffTex, texCoord), 2.2);

// 在最后输出前,对输出像素值的校正代码
fragColor.rgb = pow(fragColor.rgb, 1.0/2.2);
return fragColor;

18.4.3 什么是 HDR

高动态范围(High Dynamic Range, HDR),与之相对的是低动态范围(Low Dynamic Range, LDR)。通俗来讲,动态范围指的就是最高和最低的亮度值之间的比值。HDR 使用远远高于8位的精度(如32位)来记录亮度信息,是的我们可以表示超过0~1内的亮度值,从而可以更加精确的反应真实的光照环境。

Nvidia 曾总结过使用 HDR 进行渲染的“动机”:让亮的物体可以真的非常亮,暗的物体可以真的非常暗,同时又可以看到两者之间的细节。

使用 HDR 来存储的图像被称为高动态范围图像(HDRI),可以作为 Skybox。HDR 还可以用于光照叠加,开启后可以保留这些超过范围的光照结果,最后可以色调映射(tonemapping)将控制过程将他们转换到 LDR。

HDR 的使用可以允许我们在屏幕后处理中拥有更多的控制权,例如我们常常使用 HDR 和 Bloom 效果。

总体来说,使用 HDR 可以让我们不会丢失高亮度区域的颜色值,提供更真实的光照效果,并为一些屏幕后处理提供了更多的控制能力。但 HDR 也有自身的缺点:

  • 由于使用了浮点缓冲来存储高精度图像,不仅需要更大的显存空间,渲染速度会变慢
  • 一些硬件并不支持
  • 无法再利用硬件的抗锯齿功能,但可以使用基于屏幕后处理的抗锯齿来弥补

在 Unity 中使用 HDR,只需要在 Camera 组件面板中打开 HDR 选项。

18.4.4 那么,PBS 适合什么样的游戏

PBS 的优点在于,我们只需要一个万能的 Shader 就可以渲染很多类型的材质,而不是使用传统的做法为每种材质写特定 Shader。

PBS 的代价有:

  • 需要更复杂的光照配合。例如大量使用光照探针和反射谈怎
  • 需要开启 HDR 以及一些必不可少的屏幕特效,例如抗锯齿、Bloom、色调映射,会消耗很多性能
  • 会使美术资源更难制作。需要创建更加细腻复杂的纹理集,包括金属值纹理、高光反射纹理、粗糙度纹理、遮挡纹理、细节纹理等。

工具:Allegorithmic Substance Painter,Quixel Suite

18.5 扩展阅读

  1. Unity 官方博客《全局光照》 global-illumination-in-unity-5:简明的阐述了全局光照的解决方案
  2. Unity 官方博客 working-with-physically-based-Shading-a-practical-approach/、physically-based-shading-in-unity-5-a-primer/:介绍了 Standard Shader 的用法和注意事项
  3. Unity 基于物理着色器的示例项目 Viking Village,Shader Calibration Scene,Corridor Lighting Example:介绍如何使用 Unity 5 全新的 Standard Shader 和全局光照系统
  4. 电影短片 The Blacksmith:资源商店里,例如,人物角色使用的 Shader、头发使用的 Shader、人物阴影、大气次散射等
  5. Unity 相关教程:图形,Unity5 的光照概览,光照和渲染,Standard Shader 视频教程
  6. Unite 2014:Anton Hand 在他的演讲中给出了很多关于如何创建 PBS 中使用的资源的最佳实践,Renaldas Zioma 和 Erland Korner 讲解了如何在 Unity 5 中更加有效的使用 PBS
  7. SIGGRAPH 2015:Unity 技术人员分享了 The Blacksmith 的环境制作过程
  8. SIGGRAPH:
    1. Disney 公布了他们在离线渲染时使用的 BRDF 模型,这也是 Unity 等很多游戏引擎使用的 PBR 的理论基础
    2. Kostas Anagnostou 在他的文章中列出了非常多的关于 PBR 的相关文章
  9. 龚敏敏在他的 KlayGE 引擎中引入了 PBS,并写了系列博文来简明地阐述其中的理论基础
  10. 知乎专栏 Behind the Pixels:作者给出了3篇关于基于物理着色的系列文章

18.6 参考文献

略,请参考原书。

999. Ref

  1. Naty Hoffman on SIGGRAPH 2013: Background: Physics and Math of Shading
  2. 官方示例项目 Shader Calibration Scene:https://www.assetstore.unity3d.com/en/#!/content/25422(*失效了*)
  3. 官方示例项目 Viking Village:https://www.assetstore.unity3d.com/en/#!/content/29140(*失效了*)

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 cdd@ahucd.cn

×

喜欢就点赞,疼爱就打赏

B站 cdd的庇护之地 github itch