Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 如何在四边形上进行法线的双线性插值?_Opengl_Glsl_Interpolation - Fatal编程技术网

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

Opengl 如何在四边形上进行法线的双线性插值?,opengl,glsl,interpolation,Opengl,Glsl,Interpolation,我正在做一个像Minecraft一样的引擎,作为一个爱好项目,看看体素地形的概念在现代硬件和OpenGL>=3上可以推进多远。所以,我所有的几何体都是由四边形组成的,精确地说是正方形 我已经建立了一个光线投射器来估计环境遮挡,并使用“弯曲法线”技术来进行照明。所以我的法线不垂直于四边形,也没有单位长度;相反,它们大致指向发生遮挡最少的空间,当四边形接收到较少的光时,它们会更短。这种技术的优点是,它只需要一次性计算遮挡,并且在渲染时基本上是免费的 但是,当我试图为同一四边形的不同顶点指定不同法线以

我正在做一个像Minecraft一样的引擎,作为一个爱好项目,看看体素地形的概念在现代硬件和OpenGL>=3上可以推进多远。所以,我所有的几何体都是由四边形组成的,精确地说是正方形

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

但是,当我试图为同一四边形的不同顶点指定不同法线以获得平滑照明时,我遇到了麻烦。由于四边形被拆分为三角形,并且线性插值发生在每个三角形上,因此插值结果清楚地显示三角形作为丑陋的对角线瑕疵的存在:

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

我可以想出一些变通办法:

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

  • 使用“顶点属性”将所有4条法线附着到每个顶点。还将一些[0..1]系数附加到每个顶点,就像纹理坐标一样,并在片段着色器中执行双线性插值。这样做的代价是将4条法线传递给着色器,而不是仅传递1条法线

  • 我认为这两种技术都可以发挥作用,但我觉得它们对于应该简单得多的东西来说是个难题。也许我可以通过某种方式变换法线,这样OpenGL的插值将给出一个不依赖于所使用的特定三角剖分的结果

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


    还有其他办法解决这个问题吗?如果不是,以上两种技术中哪一种最好?

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

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

    不过,您可以使用一些技巧来简化流程

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

      • 嗯。。。在使用“弯曲法线”技术时,增加结果的最佳方法是预细分网格,然后使用细分程度较高的网格重新计算


        另一种方法是在像素着色器中使用一些技巧。。。一种可能的方法是,您可以在像素着色器中自己对纹理进行插值(而不是使用内置的插值器),这对您有很大帮助。不仅限于双线性插值,还可以做得更好,F.e.双三次插值;)

        我不想增加网格密度,因为我试图推出尽可能多的块。我知道如何自己插值纹理,但如果我能帮助的话,我不想将法线存储在纹理中——因此这个问题!OpenGL3中不推荐使用GLU四边形