我正在开发一个类似 Minecraft 的引擎,作为一个业余爱好项目,看看体素地形的概念在现代硬件和 OpenGL >= 3 上可以推广到什么程度。因此,我的所有几何体都由四边形(准确地说是正方形)组成。
我构建了一个光线投射器来估计环境光遮挡,并使用“弯曲法线”技术来进行照明。所以我的法线不垂直于四边形,也没有单位长度;相反,它们大致指向遮挡最少的空间,并且当四边形接收到的光线较少时,它们会更短。这种技术的优点是它只需要一次性计算遮挡,并且在渲染时基本上是免费的。
然而,当我尝试将不同的法线分配给同一四边形的不同顶点以获得平滑的照明时,我遇到了麻烦。因为四边形被分成三角形,并且每个三角形都发生线性插值,所以插值的结果清楚地表明三角形的存在是丑陋的对角线伪影:
问题是 OpenGL 在每个三角形上使用重心插值,这是 4 个角中的 3 个角的加权和。理想情况下,我想使用双线性插值,其中所有 4 个角都用于计算结果。
我可以想到一些解决方法:
将法线填充到 2x2 RGB 纹理中,并让纹理处理器进行双线性插值。这是以片段着色器中的纹理查找为代价的。为了提高效率,我还需要将所有这些迷你纹理打包成更大的纹理。
使用顶点属性将所有 4 个法线附加到每个顶点。还将一些 [0..1] 系数附加到每个顶点,就像纹理坐标一样,并在片段着色器中进行双线性插值。发生这种情况的代价是向着色器传递 4 个法线,而不是 1 个。
我认为这两种技术都可以发挥作用,但在我看来,它们是一些本应简单得多的东西的拼凑。也许我可以以某种方式变换法线,这样 OpenGL 的插值就会给出不依赖于所使用的特定三角测量的结果。
(请注意,该问题并不特定于法线;它同样适用于颜色或需要在四边形上平滑插值的任何其他值。)
还有什么想法可以解决这个问题吗?如果不是,以上两种技术中哪一种最好?
正如您清楚地了解的那样,GL 将执行的三角形插值不是您想要的。
所以普通数据不能直接来自顶点数据。
恐怕您所设想的解决方案是您能实现的最佳解决方案。无论您选择什么,都需要将 [0..1] 系数从顶点传递到着色器(包括 2x2 纹理。您需要它们作为纹理坐标)。
不过,您可以采取一些技巧来稍微简化该过程。
- 使用顶点 ID 可以帮助您找到从顶点传递到片段着色器的顶点“角”(我们的 [0..1] 值)。对最低 2 位进行简单的位测试可以让您知道要传递哪个角,而无需输入实际的顶点数据。如果打包纹理数据,您仍然需要在纹理内传递标识符,因此这可能没有实际意义。
- 如果您使用 2x2 纹理来允许插值,则会出现(是?)一些问题。如果源一开始的精度较低,则某些纹理插值器不一定能提供高精度插值。这可能需要您将纹理数据类型更改为更高精度,以避免出现条带伪影。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)