我刚开始学习 OpenGL ES 2.0,在这个过程中我遇到了一些对我来说没有意义的术语,即使有定义。像这个:插值
从OpenGL ES 2.0 Programming Guide一书中,我看到了插值的定义:
用于从分配给图元的每个顶点的变化值为每个片段生成变化值的机制称为插值。
虽然我理解这个答案Linear Interpolation
的含义,但上面的定义对我来说没有意义。
您能否换一种说法并举例说明什么是插值?
至于“换句话说”的一般定义,您可以在网上找到一些。例如,我可以尝试向您解释:
当您有有限数量的数据试图表示无限数量的数据时,您使用插值,例如,您有 2 个点代表一条线:
对于插值,你总是需要一个表示的提示,在行的情况下你需要 2 个点(提示是“它是一条线”),假设它们是向量 A 和 B。现在解决方案是T(s) = A + s*(B-A)
任何实数 's'在两个方向都获得无尽的线路。要在 A 和 B 之间找到一条线,您需要在区间 [0, 1] 上定义“s”,以便T(0)=A
whileT(1)=B
和这是线性插值。
对于更复杂的插值,您可以稍微研究一下 openGL:
请注意,在 GL 和您的 GPU 中使用的算法比我在这里要写的要复杂和优化得多,但通常具有相同的结果。
在形状的情况下,您通常使用由 3 个向量(顶点)定义的三角形,并说它是一个三角形(您在绘制方法中说“三角形”)。在将一些矩阵应用于这些向量之后,您将在绘图缓冲区上获得它们的 2d 投影(可能发生在顶点着色器中)。现在您需要用一些颜色、纹理或颜色插值填充缓冲区中的所有这些点。首先,所有这些绘制点(实际上它们在缓冲区上的位置)都是线性插值机制的结果(您在 GL 中无法控制它)。其次,填充什么颜色通常又是线性插值:
尝试通过设置颜色指针来绘制具有不同颜色顶点的三角形。您将在整个表面上获得一个非常平滑的颜色幽灵,这是根据位置插值进行颜色线性插值的结果(您会在片段着色器中为需要绘制的每个像素获得位置插值结果)。您可以像这样手动实现这种颜色插值结果:
输入:
Vector a, b, c; //original triangle positions
Vector interpolationABC; //current fragment interpolation between a, b and c
Color colorA, colorB, colorC; //colors for vectors a, b and c
输出(此片段的颜色):
Color output = (
(a - interpolationABC).length() * colorA +
(b - interpolationABC).length() * colorB +
(c - interpolationABC).length() * colorC )
/ (
(a - interpolationABC).length() +
(b - interpolationABC).length() +
(c - interpolationABC).length() );
这种机制再次代表线性插值(实际上非常慢,但它应该可以解决问题并且非常易读)
至于非线性插值的示例,您需要一点想象力:假设我们正在绘制一个球体。为了保持简单,假设它的中心在 (0,0,0) 中,半径为 1。球体是用 N 个三角形创建的,如果 N 不够大(大多数情况下)由于性能问题,它是有点“前卫”,我们想把它弄平一点。所以我们必须打开一些灯(无论如何它只是一个没有灯的圆圈)并弄清楚如何设置法线。一方面,您可以计算由 3 个点定义的曲面的法线,每个三角形将具有唯一的法线,但会产生“迪斯科球”效果,另一方面,您知道球体的任何点“P”的法线是normalized(P-center)
或者在这种情况下是点本身。所以每个顶点法线是顶点的位置本身(所以现在每个三角形都有3个不同的法线),每个片段的法线是这些法线的插值:
如果您使用与颜色相同的插值机制,您会发现法线的长度不是“恒定的”,从而导致缺陷,迫使您使用不同的机制(非线性)。在这种特定情况下,您可以简单地对这些线性片段结果进行归一化并获得所需的结果,但在这种特定情况下,您也可以从片段位置计算法线(您可以对任何数学上可呈现的形状执行此操作)。但是知道在实践中你会得到一个奇怪的形状,它有光滑的部分和边缘,并且可能有不同大小的法线来代表一些很棒的效果,这就是为什么有很好的机制可以在形状上插入不同的参数。
同样,插值机制是一种通过只知道有限数量的数据就可以产生无限数量结果的机制(其中一种机制称为“线性插值”)。或者换句话说,正如您发布的更具体的示例:
用于从分配给图元的每个顶点的变化值为每个片段生成变化值的机制称为插值。