如何在四边形上进行法线的双线性插值?

Tho*_*mas 13 opengl interpolation glsl

我正在开发一个类似Minecraft的引擎,作为一个业余爱好项目,看看体素地形的概念可以在现代硬件和OpenGL> = 3上推动多远.因此,我所有的几何都包括四边形或正方形.

我已经建立了一个raycaster来估计环境遮挡,并使用"弯曲法线"技术来进行照明.所以我的法线不垂直于四边形,也没有单位长度; 相反,它们大致指向发生最少遮挡的空间,并且当四边形接收较少光时较短.这种技术的优点是它只需要一次性计算遮挡,并且在渲染时基本上是免费的.

但是,当我尝试将不同的法线分配给同一个四边形的不同顶点以便获得平滑的光照时,我遇到了麻烦.因为四边形被分割成三角形,并且在每个三角形上发生线性插值,所以插值的结果清楚地表明三角形的存在是丑陋的对角线伪影:

在渲染结果中可见对角线

问题是OpenGL在每个三角形上使用重心插值,这是4个角中3个的加权和.理想情况下,我想使用双线性插值,其中所有4个角都用于计算结果.

我可以想到一些解决方法:

  1. 将法线填充为2x2 RGB纹理,让纹理处理器进行双线性插值.这是以片段着色器中的纹理查找为代价的.我还需要将所有这些迷你纹理打包成更大的纹理以提高效率.

  2. 使用顶点属性将所有4个法线附加到每个顶点.还将一些[0..1]系数附加到每个顶点,非常类似于纹理坐标,并在片段着色器中进行双线性插值.这是以将4个法线传递给着色器而不是仅仅1来为代价的.

我认为这两种技术都可以发挥作用,但它们让我觉得它应该更简单.也许我可以以某种方式转换法线,因此OpenGL的插值会产生一个不依赖于所使用的特定三角测量的结果.

(请注意,问题并非特定于法线;它同样适用于需要在四边形中平滑插值的颜色或任何其他值.)

有什么想法可以解决这个问题吗?如果没有,上述两种技术中哪一种最好?

Bah*_*bar 4

正如您清楚地了解的那样,GL 将执行的三角形插值不是您想要的。所以普通数据不能直接来自顶点数据。

恐怕您所设想的解决方案是您能实现的最佳解决方案。无论您选择什么,都需要将 [0..1] 系数从顶点传递到着色器(包括 2x2 纹理。您需要它们作为纹理坐标)。

不过,您可以采取一些技巧来稍微简化该过程。

  • 使用顶点 ID 可以帮助您找到从顶点传递到片段着色器的顶点“角”(我们的 [0..1] 值)。对最低 2 位进行简单的位测试可以让您知道要传递哪个角,而无需输入实际的顶点数据。如果打包纹理数据,您仍然需要在纹理内传递标识符,因此这可能没有实际意义。
  • 如果您使用 2x2 纹理来允许插值,则会出现(是?)一些问题。如果源一开始的精度较低,则某些纹理插值器不一定能提供高精度插值。这可能需要您将纹理数据类型更改为更高精度,以避免出现条带伪影。