SubstancePaiter的CustomShader,实现美术制作引擎中复杂材质贴图时的可视化



上图使用user0中的一张灰度图来采样四张NormalMap


偶然得知painter中可以自制shader,趁着周末试了一下,结果如上。

在painter内help>documentation>shader api可以打开软件内置的api文档index。简单看一下可以知道CustomShader开放的是Fragment/pixel(他们自己叫surface)shader中的一部分,语言用的是glsl,官方制作的shader里大多数调用的函数都被封装在了下面库中,在CustomShader中可以import lib—xxx。glsl来调用。


内置库,大都是变量和函数的声明

库中内容较多,大致看了一下决定直接从官方的shader开改,在Substance Painter\resources\shelf\allegorithmic\shaders可以找到pbr-metal-rough.glsl,这应该是大家最常用的shader了,可以大致看下这个shader,1中导入库,2是channel中的贴图,3中调用的函数都在1中的库中,整个shader相当的精简。


内置库,大都是变量和函数的声明

我的目标是制作一个用一张灰度图采样4张normal来叠加到原本normal的shader,之所以选择改normal是因为normal涉及到各空间坐标的转换可以挖深一些,其余通道会相对更简单。看上述代码可以找到123部分都不涉及到normal,直到4中的computelLocalFrame();


在lib—vectors.glsl中可以找到这个函数,LocalVectors这个结构体也在这里面声明,函数中的input.normal是模型的法线而不是我们需要找的贴图法线,所以接着找computeWSNormal()这个函数。


在这进行法线的空间转换,接着找getTSNormal(),这里的TS指的是TangetSpace。


getTSNormal()的函数有两个,输入不同,上面调用的是下面的第二个,函数中计算了从高度转换来的法线并调用了第一个函数,而第一个函数就是我们要找的了,简单看下函数中解包了Channel中的基础法线和painter中绘制的法线/高度根据设置进行融合。


我们需要做得是在return normal前(基本就是使用painter制作贴图时最后会导出的贴图的unpack版)进行normal操作,这样结果就和引擎里的效果相同了


改完这个函数后需要把之前的一层层调用copy一份,层层修改函数名,最后的完整shader代码在这。总结一下Substance的shader封装的很好,各个数据调用也很方便,不管是直接用官方的PBR效果还是自己写一套光照应该都很好实现。有点奇怪的是我没有看到u_time,有人知道也可以告诉我下。