世界空间MatCap底纹

在我们的赛车/跑步游戏中,我们决定使用Matcap着色(至少目前如此)

MatCap(我想它代表“材质捕捉”)听起来像是-捕捉材质属性,如光泽/粗糙度,纹理的整体“感觉”。 它通常仅用于此目的-以较低的渲染成本创建某种材质的感觉。 MatCap通常与ZBrush关联,您可以在其网站上找到很多MatCap示例

渲染成本很低,因为整个材质距离在屏幕上渲染仅一个纹理样本。 在渲染球体本身时,所有困难且昂贵的计算都是“离线”完成的。

如前所述,MatCaps通常用于“感觉”材质。 但是也可以将它们仅用于照明目的。 我们只需要在非反射性白色球体上捕获场景照明,然后使用该球体照明场景中的任何动态对象即可。 与球谐中的情况非常相似,MatCaps的渲染速度完全不依赖于许多光源或其他任何东西。

当我们在Unity中进行照明时,其他人已经完成了很多工作。 这里有一组免费的MatCap着色器:https://www.assetstore.unity3d.com/zh-CN/#!/content/8221

但是有一个问题-这些着色器不对MatCap采样使用世界空间法线。 采样完全取决于视口角度和位置。 这意味着照明取决于相机旋转,而不取决于对象旋转。 看一看:

只需旋转相机,我们便可以更改照明条件。 照明并不是真的那样。 基本上,对于像某些自上而下的RPG之类的静态角度相机,或该相机不旋转的任何其他游戏,此设置都可以。

但是在我们的情况下,在某些情况下会发生相机旋转。 因此,我们需要能够使用世界空间法线而不是视图空间法线。 这是这样的:

如果我们围绕球体旋转相机,则会看到以下内容:

照明保持不变-白色和黑色的方向保持不变。

在更改着色器时,我还注意到沿“ 50%接缝”的一些伪像,其中纹理读取开始对球体的边缘进行采样:

我可以想到两种可能的解决方案:

  1. 纹理沿球体的边缘出血,因此每个像素进一步渗入纹理,将该白棕色边缘减小为零
  2. 稍微减小MatCap纹理采样的半径

第一种解决方案更可取,因为它可以保留这些边缘细节。 第二种解决方案虽然更简单明了,所以我决定先尝试一下:

如您所见,我们丢失了耀斑细节,但摆脱了工件。

这是不带MatCap照明的游戏中汽车的外观:

可以在https://github.com/KumoKairo/Worldspace-Normal-Lighting/blob/master/MatCap_Plain.shader中找到该着色器