编者按:

本文转载于公众号:戴老师的 CG 日常     

作者:戴巍

如需转载请与原公众号或原作者联系。


问题与目的:

这是一篇高级的材质技巧教程。讲的是使用菲涅尔公式中的 n 值和 k 值来定义材质的方法。

一般情况下,我们会使用 IOR 或者 F0 来定义材质的正面反射率,再配合 Reflection color 来定义反射颜色,藉此可定义绝大多数常规的非金属或者金属材质。
一般来说,标准非金属材质很容易处理,IOR = 1.5,或者 F0 = 0.04 的时候,材质的反射表现为标准非金属材质,可以理解为物理正确。以上也是 PBR 流程对于非金属材质的标准化处理方式,艺术家遵循该标准很难出错,效果也容易统一。

但是金属材质则很多时候会使用 IOR 大于 20 以上的数值 ,或者 F0 大于 0.4 以上的数值来制作。这种做法过多依赖个人经验和临场发挥,材质可能会在制作过程中由于个人理解的差异而差异较大。

也就是说制作金属材质的时候,缺乏一套行之有效的统一标准。容易导致流程的混乱,最终效果出问题的时候,你不知道问题是出在材质还是灯光还是贴图。

本文希望通过复杂菲涅尔(complex fresnel)方法,解决材质所导致的混乱问题。

介绍:

complex fresnel,这个名字来自 vray 官方帮助文档:

https://docs.chaosgroup.com/display/OSLShaders/Complex+Fresnel+shader

这篇文章中提供了一个 osl 材质,叫做 complex fresnel shader,作用是可以使用 n值 和 k 值,这两个存在于菲涅尔公式中的参数来定义材质的具体反射表现。

帮助文档是提供了这个 osl 材质的源码:
float fresnel(float n, float k, float c) {
float k2=k*k;
float rs_num = n*n + k2 – 2*n*c + c*c;
float rs_den = n*n + k2 + 2*n*c + c*c;
float rs = rs_num/ rs_den ;

float rp_num = (n*n + k2)*c*c – 2*n*c + 1;
float rp_den = (n*n + k2)*c*c + 2*n*c + 1;
float rp = rp_num/ rp_den ;

return clamp(0.5*( rs+rp ), 0.0, 1.0);
}

shader complex_ior (
vector n=vector(0.27105, 0.67693, 1.3164) [[ string description = “Refractive index for red, green, blue wavelengths (f.e. for 0.65, 0.55, 0.45 micrometers)” ]],
vector k=vector(3.6092, 2.6247, 2.2921) [[ string description = “Extinction coefficient for red, green, blue wavelengths (f.e. for 0.65, 0.55, 0.45 micrometers)” ]],
output color Col_Out = color(0.5)
)
{
float thetaCos = abs(dot(-I,N));
float red=fresnel(n[0], k[0], thetaCos);
float green=fresnel(n[1], k[1], thetaCos);
float blue=fresnel(n[2], k[2], thetaCos);
Col_Out=color(red, green, blue);
}

我知道你在想什么,我也看不懂。没关系,对于艺术家来说,我们只要知道如何使用就好。

关于查询网站以及 GW 教程中的错误:

首先我们需要用到一个网站:

http://refractiveindex.info/

大概长这样:

这是一个科学测算材质相关方方面面参数的网站,可以查到非常多有用的信息。本文介绍的做法非常依赖这个网站查询所获得的参数。我们后面要在材质球上使用的 n 值和 k 值就是在这里查询出来的。

如果是看过 grant warwick 的 mastering V-Ray 教程的朋友,应该对这个网站不会陌生。

在这套经典材质教程中,作者并没有使用常规方式去制作材质的反射,而是自定义了三个反射曲线对应红绿蓝三个通道,藉此制作出非常复杂而丰富的反射效果。他制定 RGB 反射曲线的信息来源就是上面提到的这个网站。他会先查自己想要制作的材质,然后获得一个图,大概这样:

grant warwick 在教程中说,这三根红绿蓝曲线代表的是红绿蓝三个通道的反射率。横轴是相机视线与模型表面法线的夹角度数,纵轴是反射率。并且使用一些类似曲线的工具去手动还原查询到的这张图。

然而这张图上写得很清楚,红色曲线代表的是 S-polarized,蓝色曲线代表 P-polarized,绿色曲线代表的是 non-polarized。这里说的其实是偏振光的的反射,而不是红绿蓝的反射。因为跟主题关系不大就不深究了。

总之,grant warwick 在曾经的 mastering V-Ray 教程中教授的方法并不正确,但是他以自己艺术家敏锐的眼光调来调去,弥补了技术上的失误,最后的效果总的来说还是不错的。

正确使用方法:

首先在 shelf 一栏中选择给三维艺术家使用的数据,后面的类型可以根据自己的需要进行选择。比如我可以选择大类型金属(metals),细分类型铁(Fe)。

之后,根据 vray 官方帮助文档上的信息,使用参数:红光波长 0.65 微米,绿光波长 0.55 微米,蓝光波长 0.45 微米。
将这些参数代入网站的计算器中计算出对应的 n 值和 k 值:

红光的 n 值和 k 值:

绿光的 n 值和 k 值:

蓝光的 n 值和 k 值:

这个时候,再将对应的 n 值和 k 值使用到渲染器中的材质球上去即可以获得精确的材质效果。应为 Redshift 渲染器的材质球已经内置了 n 值和 k 值,所以,后面的渲染测试我都在 Redshift 渲染器当中进行。如果是别的渲染器,只要支持 osl 材质的,都可以在上文提供的 vray 官方帮助文档中下载 complex_ior.zip 文件,获得complex fresnel shader,之后再将这个 osl 材质计算出来的结果插入标准材质的 reflection color 里面去,关闭材质本身的 fresnel 功能,即可获得和本文后面一样的效果。

在 Redshift 的 RsMaterial 材质上,fresnel type 使用 IOR(Advanced)即可开启材质的 n 值和 k 值,下图中的 IOR 一栏即为 n 值,Absorption(k)一栏即为k值。 第一列为红光的n值和k值,第二列为绿光的 n 值和 k 值,第三列为蓝光的 n 值和 k 值。

铁(Fe):

铜(Copper):

铝(Aluminum)

金(Gold)

总结:

应该有很多人比较关心用 complex fresnel 方法做出来的效果和传统方法比有多少差距。我对比的结果是比较小,不用 AB 对比几乎看不太出来,所以我就不把图发出来了,因为你们看不到 AB 对比会觉得效果完全一样没区别。(可能我做的案例还不够体现出问题来,还需要更多的测试)

虽然说 complex fresnel 最终效果和传统做法效果差不多,但是我觉得很大的意义是它所提供的参考价值。你想想你用传统的做法,让你调一个金子的材质,你知道金的颜色到底要给多少?IOR 或者 F0 要给多少? 还不是靠感觉。但你的感觉可能会受到你的灯光所影响,或者别的物体颜色影响等等,你每次调的结果可能都不同。就是开篇提的问题,传统的做法没有标准,很难统一,尤其在大项目里容易造成后环节的混乱(到底是照着你的材质改灯光,还是打回去重新改材质)。如果说用 complex fresnel 的标准做法,那么材质可以确定是准确的,最终效果有问题可以排除是材质的问题,那么修改的就是灯光或者别的东西。

我在这个问题上的研究还不够深入,希望这篇教程可以起到抛砖引玉的作用,引发大家对现有流程的思考,我们是否还可以做到更好呢?
应该是可以的。国内的材质水平相当落后,很明显是所有流程中很明显的一块短板,最近看到狮子王的宣传片,差距过于巨大,我都想蒙上自己的双眼。

我们还有很长的一段路要走。材质,材质!

(渲染图加了 LUT 开了 post FX,也就是 octane 那一套,你可以理解为卖家秀。不过手机上小图估计只能看个大感觉)

Categories: News

相关文章(Related Posts)