正确的glsl仿射纹理映射

vel*_*yel 5 opengl math glsl texture-mapping

我正在尝试在GLSL中编码正确的2D仿射纹理映射.

说明:

...没有这个图像对我的目的是正确的.右(标记为正确)具有我不想要的透视校正.所以这个:了解Q纹理坐标解决方案(没有进一步的改进)并不是我想要的.

我想简单地在四边形内"拉伸"纹理,如下所示:

在此输入图像描述

但是由两个三角形组成.有什么建议(GLSL)好吗?

Jes*_*ssy 6

只要你有一个梯形,它就可以正常工作,并且它的平行边与一个局部轴对齐.我建议玩我的Unity包.

GLSL:

varying vec2 shiftedPosition, width_height;

#ifdef VERTEX
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    shiftedPosition = gl_MultiTexCoord0.xy; // left and bottom edges zeroed.
    width_height = gl_MultiTexCoord1.xy;
}
#endif

#ifdef FRAGMENT
uniform sampler2D _MainTex;
void main() {
    gl_FragColor = texture2D(_MainTex, shiftedPosition / width_height);
}
#endif
Run Code Online (Sandbox Code Playgroud)

C#:

// Zero out the left and bottom edges, 
// leaving a right trapezoid with two sides on the axes and a vertex at the origin.
var shiftedPositions = new Vector2[] {
    Vector2.zero,
    new Vector2(0, vertices[1].y - vertices[0].y),
    new Vector2(vertices[2].x - vertices[1].x, vertices[2].y - vertices[3].y),
    new Vector2(vertices[3].x - vertices[0].x, 0)
};
mesh.uv = shiftedPositions;

var widths_heights = new Vector2[4];
widths_heights[0].x = widths_heights[3].x = shiftedPositions[3].x;
widths_heights[1].x = widths_heights[2].x = shiftedPositions[2].x;
widths_heights[0].y = widths_heights[1].y = shiftedPositions[1].y;
widths_heights[2].y = widths_heights[3].y = shiftedPositions[2].y;
mesh.uv2 = widths_heights;
Run Code Online (Sandbox Code Playgroud)


vel*_*yel -2

感谢您的回答,但经过实验我找到了解决方案。

左边的两个三角形有 uv (strq) 根据这个,右边的两个三角形是这个透视校正的修改版本。

数字和着色器:

tri1 = [Vec2(-0.5, -1), Vec2(0.5, -1), Vec2(1, 1)]
tri2 = [Vec2(-0.5, -1), Vec2(1, 1), Vec2(-1, 1)]

d1 = length of top edge = 2
d2 = length of bottom edge = 1

tri1_uv = [Vec4(0, 0, 0, d2 / d1), Vec4(d2 / d1, 0, 0, d2 / d1), Vec4(1, 1, 0, 1)]
tri2_uv = [Vec4(0, 0, 0, d2 / d1), Vec4(1, 1, 0, 1), Vec4(0, 1, 0, 1)]
Run Code Online (Sandbox Code Playgroud)

使用此 glsl 着色器仅渲染直角三角形(左侧是固定管道):

void main()
{
    gl_FragColor = texture2D(colormap, vec2(gl_TexCoord[0].x / glTexCoord[0].w, gl_TexCoord[0].y);
}
Run Code Online (Sandbox Code Playgroud)

所以..只有U是透视的,V是线性的。

  • 这正是我向您展示的内容,只是它没有考虑那么多案例。有六个顶点是没有用的。 (3认同)