目录 |
1 高亮的高光 1.1 光滑度 1.2 表面数据 1.3 漫反射光 1.4 镜面选项 1.5 镜面高光 1.6 逐物体平滑度 2 反射环境 2.1 采样环境 2.2 调制反射 2.3 菲涅尔 2.4 金属表面 3 非同一的缩放值 3.1 移除假设条件 4 反射探针 4.1 盒投影 4.2 探针混合 4.3 HDR解码 5 透明表面 5.1 预乘Alpha 5.2 预设 |
本文重点:
1、添加镜面高光
2、反射环境
3、支持非同一的缩放
4、和反射探针一起工作
5、结合反射和透明度
这是涵盖Unity的可脚本化渲染管道的教程系列的第七部分。它涵盖了反射,镜面高光和采样反射探针的添加。
本教程是CatLikeCoding系列的一部分,原文地址见文章底部。“原创”标识意为原创翻译而非原创教程。
本教程使用Unity 2018.3.0f2制作。
(倒影生动起来)
1 高亮的高光
到目前为止,我们仅使用了简单的漫射照明,没有任何照明。我们现在将改变它,增加对镜面照明的支持。我们将使用与Unity的Lightweight渲染管道中使用的模型相同的模型。“渲染4,拳头照明”教程介绍了镜面照明的原理,但使用了不同的模型。
1.1 光滑度
完美的漫反射表面(即完美的漫射器)根本没有镜面反射。表面是如此粗糙,以至于没有聚焦反射发生。表面越光滑,反射的光线就越多,而不是扩散。我们将通过从0到1的平滑度材料属性(默认值为?)进行控制。
(光滑度 滑动条)
添加相应的着色器变量。
1.2 表面数据
囊括镜面反射会使我们的照明模型更加复杂。让我们将其所有代码放在一个单独的文件Lighting.hlsl中。在里面定义一个LitSurface结构,该结构包含执行照明计算所需的所有表面数据。那就是表面的法线,位置,漫反射和镜面反射的颜色及其粗糙度。还会包含视图方向,它实际上不是表面的属性,但是相对于我们正在使用的表面点而言是恒定的。
添加一个GetLitSurface函数,该函数返回Lit的表面数据。在此HLSL文件中,我们将不依赖于着色器特定的属性,纹理或定义,因此必须将所有相关数据定义为参数。尽管我们把平滑度作为输入,但是在内部,我们使用粗糙度,只是反过来而已。此外,我们现在使用金属工作流程并将自己局限于电介质材质。介电材质是非金属的,仅反射少量的光,相当于平均0.04的灰度镜面反射。就像Unity的光照代码一样,我们将对其进行硬编码。
根据迪斯尼模型(Disney model),此时我们拥有的粗糙度实际上是一个称为感知粗糙度的值。物理粗糙度是其平方。我们都需要。
在Lit.hlsl中包含Lighting.hlsl。
现在,在执行任何光照计算之前,我们可以在LitPassFragment中获取表面。视线方向就是相机位置减去片段位置(归一化)。
1.3 漫反射光
我们将把照明计算移到Lighting.hlsl。为此,为其提供一个LightSurface函数,以表面和光的方向为参数。它执行漫反射点乘积,并将其乘以表面的漫反射色。我们假设这里是理想的光线,纯白色而没有衰减。
调整MainLight,使其仅将表面作为参数,而不是位置和法向矢量。让它调用LightSurface而不是执行点乘积本身。和以前一样,在此处应用衰减和光色。
以相同的方式调整DiffuseLight,将其重命名为GenericLight,从现在开始可以更好地描述其目的。
现在,LitPassFragment必须将表面作为参数传递。而且,漫反射现在也沿途(而不是在末尾)计入颜色。在开始时,我们仍然必须将其纳入顶点照明。
我们还必须对顶点灯光使用GenericLight。顶点照明是纯漫反射的,因此仅需要位置和法线。颜色为白色,其他值无关紧要。让我们为Lighting.hlsl添加一个方便的包装函数。
然后在LitPassVertex中使用它。
1.4 镜面选项
在添加镜面高光之前,让我们可以跳过它,以便仍然支持完美的漫反射材质。我们将通过添加到表面并作为GetLitSurface的参数的布尔字段来指示默认情况下将其设置为false。这个想法是,你可以对参数进行硬编码,或者使其依赖于着色器关键字。
如果是完美的散光器(diffuser),则平滑度和镜面反射度应始终为零。