所以我正在尝试在顶点着色器中为图像添加旋转和透视效果。旋转效果正常,但我无法实现透视效果。我正在2D环境下工作。
旋转矩阵是从代码生成的,但透视矩阵是我使用透视工具从GIMP获得的一堆硬编码值。
private final Matrix3 perspectiveTransform = new Matrix3(new float[] {
0.58302f, -0.29001f, 103.0f,
-0.00753f, 0.01827f, 203.0f,
-0.00002f, -0.00115f, 1.0f
});
这个透视矩阵在GIMP中500x500像素的图像上产生了我想要的结果。现在我尝试在纹理坐标上应用同样的矩阵,所以我先乘以500再除以500。
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
uniform mat3 u_rotation;
uniform mat3 u_perspective;
varying vec4 v_color;
varying vec2 v_texCoords;
void main() {
v_color = a_color;
vec3 vec = vec3(a_texCoord0 * 500.0, 1.0);
vec = vec * u_perspective;
vec = vec3((vec.xy / vec.z) / 500.0, 0.0);
vec -= vec3(0.5, 0.5, 0.0);
vec = vec * u_rotation;
v_texCoords = vec.xy + vec2(0.5);
gl_Position = u_projTrans * a_position;
}
针对旋转,我会偏移原点以使其绕中心而非左上角旋转。
我所知道的关于GIMP透视工具的信息大部分来自http://www.math.ubc.ca/~cass/graphics/manual/pdf/ch10.ps。阅读后,该链接建议我可以重现GIMP的效果,但事实证明我不能。结果没有显示(没有像素),而删除透视部分会正确旋转图像。
如链接中所述,我将我的齐次坐标除以
vec.z
以将其转换回2D点。我没有使用原点移位进行透视变换,因为链接中提到左上角被用作原点。第11页:
编辑:有一件事需要小心 - GIMP坐标的原点在左上角,y向下增加。
感谢@Rabbid76的答案,现在它正在显示内容!然而,它并没有像矩阵在GIMP上变换我的图像。
我的 GIMP 变换矩阵应该做了一些类似于这样的事情: 但实际上,它看起来像这样: 这是我从实际结果中看到的想法: https://imgur.com/X56rp8K(使用Image)
(正如指出的那样,它的纹理参数被夹在边缘而不是夹在边框上,但这不是重点)
看起来它正在做我要寻找的相反的事情。我尝试在应用矩阵之前将原点偏移到图像的中心和左下角,但没有成功。这是一个新的结果,但问题仍然存在:如何将GIMP透视矩阵应用到GLSL着色器中? 编辑2:
经过更多测试,我可以确认它正在做“相反”的事情。使用这个简单的缩小转换矩阵:
private final Matrix3 perspectiveTransform = new Matrix3(new float[] {
0.75f, 0f, 50f,
0f, 0.75f, 50f,
0f, 0f, 1.0f
});
结果是图像的放大版本: 如果我以编程方式反转矩阵,它对于简单的缩放矩阵有效!但对于透视矩阵,则显示为:
编辑3::
再次感谢@Rabbid76,结果证明在透视矩阵之后应用旋转会使旋转在透视之前进行,我得到了这样的结果:https://imgur.com/n1vWq0M
接近成功!唯一的问题是图像非常扭曲。就像应用了多次透视矩阵一样。但是如果你仔细看,你可以看到它在透视中旋转,就像我想要的那样。现在的问题是如何取消扭曲,以获得与GIMP中相同的结果。(根本问题仍然是如何将GIMP矩阵应用于着色器)
inv()
方法来反转矩阵。这在你提供的答案中并非如此。 - Winter