在尝试了这里和其他地方提出的许多解决方案后,我最终通过编写一个片段着色器来复制“warpPerspective”的功能来解决了这个问题。
片段着色器代码大致如下:
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp mat3 inverseHomographyMatrix;
uniform highp float width;
uniform highp float height;
void main()
{
highp vec3 frameCoordinate = vec3(textureCoordinate.x * width, textureCoordinate.y * height, 1.0);
highp vec3 m = inverseHomographyMatrix[2] * frameCoordinate;
highp float zed = 1.0 / (m.x + m.y + m.z);
frameCoordinate = frameCoordinate * zed;
highp float xTrans = inverseHomographyMatrix[0][0] * frameCoordinate.x + inverseHomographyMatrix[0][1] * frameCoordinate.y + inverseHomographyMatrix[0][2] * frameCoordinate.z;
highp float yTrans = inverseHomographyMatrix[1][0] * frameCoordinate.x + inverseHomographyMatrix[1][1] * frameCoordinate.y + inverseHomographyMatrix[1][2] * frameCoordinate.z;
highp vec2 coords = vec2(xTrans / width, yTrans / height);
if (coords.x >= 0.0 && coords.x <= 1.0 && coords.y >= 0.0 && coords.y <= 1.0) {
gl_FragColor = texture2D(inputImageTexture, coords);
} else {
gl_FragColor = vec4(0.0,0.0,0.0,0.0);
}
}
请注意,我们在这里传递的单应矩阵是
反向单应矩阵!您必须反转传递到“warpPerspective”的单应矩阵-否则此代码将无法正常工作。
顶点着色器除了通过坐标外什么也不做:
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main() {
textureCoordinate = inputTextureCoordinate.xy;
gl_Position = position;
}
将未经修改的纹理坐标和位置坐标传入(即textureCoordinates =[(0,0),(0,1),(1,0),(1,1)]和positionCoordinates = [(-1,-1),(-1,1),(1,-1),(1,1)],对于三角形带),这样应该就可以工作了!