Opengl 为什么边界纹理在使用双线性过滤放大/缩放时会获得相同的颜色?

Opengl 为什么边界纹理在使用双线性过滤放大/缩放时会获得相同的颜色?,opengl,shader,Opengl,Shader,与双线性滤波一样,采样颜色是基于4个最近的纹理的加权平均值计算的,那么为什么角纹理在放大时得到相同的颜色 例如: 在这种情况下,当使用双线性过滤将3x3图像放大/缩放为5x5像素图像时,下面的图像角“红色”像素也会获得完全相同的颜色和边框“绿色” 在一些文件中,,有人解释说,角点纹理以相同的颜色扩展,得到4个相邻的纹理,这解释了为什么角点“红色”纹理在5x5图像中得到相同的颜色,但如果根据4个最近的纹理的加权平均值计算边界“绿色”纹理,为什么会得到相同的颜色不对。将其视为从目标像素位置到源像素位

与双线性滤波一样,采样颜色是基于4个最近的纹理的加权平均值计算的,那么为什么角纹理在放大时得到相同的颜色

例如:

在这种情况下,当使用双线性过滤将3x3图像放大/缩放为5x5像素图像时,下面的图像角“红色”像素也会获得完全相同的颜色和边框“绿色”


在一些文件中,,有人解释说,角点纹理以相同的颜色扩展,得到4个相邻的纹理,这解释了为什么角点“红色”纹理在5x5图像中得到相同的颜色,但如果根据4个最近的纹理的加权平均值计算边界“绿色”纹理,为什么会得到相同的颜色不对。将其视为从目标像素位置到源像素位置的映射。因此,对于每个设计像素,都有一个与之对应的源坐标。该源坐标决定了4个相邻像素以及分配给它们的双线性权重

让我们用0,0在左上角为像素编号

目标图像中的像素0,0映射到源图像中的坐标0,0。源图像中的四个相邻像素是0、0、1、0、0、1和1、1。我们用简单的数学计算双线性权重:特定像素在X方向上的权重是1-pixel.X-source.X,其中source是源坐标。Y也是如此。因此,四个相邻像素中每一个的双线性权重分别对应于上述顺序:1、1、0、0、0、0和0、0


简而言之,因为目标像素精确地映射到源像素,所以它会精确地获取该源像素的值。这是应该的。

您对双线性插值的理解不正确。将其视为从目标像素位置到源像素位置的映射。因此,对于每个设计像素,都有一个与之对应的源坐标。该源坐标决定了4个相邻像素以及分配给它们的双线性权重

让我们用0,0在左上角为像素编号

目标图像中的像素0,0映射到源图像中的坐标0,0。源图像中的四个相邻像素是0、0、1、0、0、1和1、1。我们用简单的数学计算双线性权重:特定像素在X方向上的权重是1-pixel.X-source.X,其中source是源坐标。Y也是如此。因此,四个相邻像素中每一个的双线性权重分别对应于上述顺序:1、1、0、0、0、0和0、0


简而言之,因为目标像素精确地映射到源像素,所以它会精确地获取该源像素的值。这是应该的。

当使用双线性纹理采样时,纹理中的纹理不会被视为彩色正方形,而是作为连续颜色场的采样。这是红绿色棋盘的此字段,其中纹理边界被勾勒出来:

圆圈表示纹理的纹理,即纹理的采样位置。通过双线性插值计算样本之间的颜色。作为一种特殊情况,两个相邻纹理之间的插值是一种简单的线性插值。当x介于0和1之间时,则:color=1-x*leftColor+x*rightColor

插值方案仅定义采样之间的区域中发生的情况,即甚至不到纹理的边缘。OpenGL用来确定缺失区域的是纹理或采样器的包裹模式。如果使用GL_CLAMP_TO_EDGE,则该边的texel值将像上面的示例一样重复。通过这个,我们为任意纹理坐标定义了颜色场

现在,当我们渲染5x5图像时,碎片的颜色将在像素中心计算。如下图所示,碎片评估位置用黑点标记:

假设绘制了一个纹理坐标范围为0到1的全屏四边形,则碎片计算位置处的纹理坐标是顶点纹理坐标的插值。现在我们可以用片段覆盖之前的颜色场,我们将找到双线性采样器产生的颜色:

我们可以看到以下几点:

中心碎片与红色纹理完全一致,因此得到完美的红色。 边缘上的中心碎片正好落在两个绿色样本之间,其中一个样本是纹理外部的虚拟样本。因此,他们得到了完美的绿色。这是由于包裹模式。其他包裹模式会产生不同的颜色。然后插值为:color=1-t*outsideColor+t*insideColor,其中t=3*0.5/5+0.5/3=0.8是插值参数。 角点片段也是f的插值 我们的texel颜色为纹理内部的1个真实颜色和外部的3个虚拟颜色。同样,由于包装模式,这些将得到一个完美的红色。 所有其他颜色都是红色和绿色的插值。
使用双线性纹理采样时,纹理中的texel不会被视为彩色正方形,而是被视为连续颜色场的采样。这是红绿色棋盘的此字段,其中纹理边界被勾勒出来:

圆圈表示纹理的纹理,即纹理的采样位置。通过双线性插值计算样本之间的颜色。作为一种特殊情况,两个相邻纹理之间的插值是一种简单的线性插值。当x介于0和1之间时,则:color=1-x*leftColor+x*rightColor

插值方案仅定义采样之间的区域中发生的情况,即甚至不到纹理的边缘。OpenGL用来确定缺失区域的是纹理或采样器的包裹模式。如果使用GL_CLAMP_TO_EDGE,则该边的texel值将像上面的示例一样重复。通过这个,我们为任意纹理坐标定义了颜色场

现在,当我们渲染5x5图像时,碎片的颜色将在像素中心计算。如下图所示,碎片评估位置用黑点标记:

假设绘制了一个纹理坐标范围为0到1的全屏四边形,则碎片计算位置处的纹理坐标是顶点纹理坐标的插值。现在我们可以用片段覆盖之前的颜色场,我们将找到双线性采样器产生的颜色:

我们可以看到以下几点:

中心碎片与红色纹理完全一致,因此得到完美的红色。 边缘上的中心碎片正好落在两个绿色样本之间,其中一个样本是纹理外部的虚拟样本。因此,他们得到了完美的绿色。这是由于包裹模式。其他包裹模式会产生不同的颜色。然后插值为:color=1-t*outsideColor+t*insideColor,其中t=3*0.5/5+0.5/3=0.8是插值参数。 角点片段也是来自四种纹理颜色的插值,一种是纹理内部的真实颜色,另一种是纹理外部的虚拟颜色。同样,由于包装模式,这些将得到一个完美的红色。 所有其他颜色都是红色和绿色的插值。
你确定这是准确的吗?下角片段的纹理坐标为0.5/5,0.5/5=0.1,在像素中心采样0.1个片段。该纹理坐标与纹理位置不一致,最近的坐标为0.5/3,0.5/3=0.166,0.166。因此,采样的颜色实际上是角纹理和纹理外部三个纹理的插值。然后取决于夹紧设置。我试图检查数学,但图像中似乎有一些色调映射。棕色不是红色和绿色的直接插值。尼科,是的,这就是我正在使用的计算,这就是为什么我对边界绿色纹理是全绿色感到困惑的原因。至少有2个相邻的纹理应该是红色的?@user2259784绿色的纹理更明显一些。它们的采样坐标正好位于两个texel之间,一个分量为0.5。如果夹持模式是“重复”或“夹持”,这是绿色和绿色之间的插值。我对红色的角点像素比较困惑。顺便说一句,你的夹紧方式是什么?如果是钳形,那么这就是你的答案。@NicoSchertler,你能解释一下当采样坐标正好位于两个texel之间时,如何根据4个texel的加权平均值计算texel颜色吗?图像在夹具中mode@NicoSchertler:纹理坐标我从未将任何东西称为纹理坐标。我说过我们将对像素进行编号,而不是对它们进行规格化。你确定这是准确的吗?下角片段的纹理坐标为0.5/5,0.5/5=0.1,在像素中心采样0.1个片段。该纹理坐标与纹理位置不一致,最近的坐标为0.5/3,0.5/3=0.166,0.166。因此,采样的颜色实际上是角纹理和纹理外部三个纹理的插值。然后取决于夹紧设置。我试图检查数学,但图像中似乎有一些色调映射。棕色不是红色和绿色的直接插值。尼科,是的,这就是我正在使用的计算,这就是为什么我对边界绿色纹理是全绿色感到困惑的原因。至少有2个相邻的纹理应该是红色的?@user2259784绿色的纹理更明显一些。它们的采样坐标正好位于两个texel之间,一个分量为0.5。如果夹持模式是“重复”或“夹持”,这是绿色和绿色之间的插值。我对红色更困惑
角点像素。顺便说一句,你的夹紧方式是什么?如果是钳形,那么这就是你的答案。@NicoSchertler,你能解释一下当采样坐标正好位于两个texel之间时,如何根据4个texel的加权平均值计算texel颜色吗?图像在夹具中mode@NicoSchertler:纹理坐标我从未将任何东西称为纹理坐标。我说我们将对像素进行编号,而不是对它们进行规格化。