Opengl es 使用opengl es 2.0在glsl中执行透视扭曲时如何正确映射纹理

Opengl es 使用opengl es 2.0在glsl中执行透视扭曲时如何正确映射纹理,opengl-es,glsl,shader,texture-mapping,perspective,Opengl Es,Glsl,Shader,Texture Mapping,Perspective,我正在尝试使用顶点着色器和片段着色器创建四角透视效果 我将顶点位置信息设置为绘制类似透视图的形状,然后在其上映射纹理。但不知何故,纹理没有正确映射 这里有两张图片向你展示这个问题 我从中发现一些信息,texture2DProj可能是正确的答案,但我不太明白它是如何工作的。我试着做这样的事 varying lowp vec4 TexCoordOut; uniform sampler2D Texture; void main(void) { gl_FragC

我正在尝试使用顶点着色器和片段着色器创建四角透视效果

我将顶点位置信息设置为绘制类似透视图的形状,然后在其上映射纹理。但不知何故,纹理没有正确映射

这里有两张图片向你展示这个问题

我从中发现一些信息,texture2DProj可能是正确的答案,但我不太明白它是如何工作的。我试着做这样的事

    varying lowp vec4 TexCoordOut;
    uniform sampler2D Texture;

    void main(void) {
        gl_FragColor = texture2DProj(Texture, TexCoordOut);
    }
而对于特克斯库德,我要通过

{1, 0, 0, 1}
{1, 1, 0, 1}
{0, 1, 0, 1}
{0, 0, 0, 1}
到顶点着色器,并将其更改为片段着色器。但结果是一样的


我只知道如何将texture2D与vec2一起使用,如何让纹理坐标的其他两个组件与texture2D一起使用?

我怀疑问题在于,您的输入坐标正在渲染2D形状,而不是3D形状,即,您的所有4个顶点都有一个恒定的Z值

与其渲染二维形状,不如渲染在三维中倾斜的正方形,不同的插值将为您进行透视正确的分割。然后可以使用普通的texture2D操作


在这种情况下,您可能不希望使用投影纹理-您可以-但这是不必要的复杂,您仍然需要为纹理坐标生成适当的w值,以使透视分割生效,因此,您也可以按顶点执行此操作,并使用可变插值器来执行繁重的操作。

如果确实要使用texture2DProj,则可以将W坐标从位置复制到纹理坐标。例如:

uniform mat4 uPrj;
attribute vec2 aXY;
attribute vec2 aST;
varying vec4 st;
void main(void) {
    vec4 pos=uPrj*vec4(aXY,0.0,1.0);
    gl_Position=pos;
    st=vec4(aST,0.0,pos.w);

    st.xy*=pos.w; // Not sure if this is needed with texture2DProj
}
然而,我绕过了透视纹理的问题,将四边形分割成一个由较小四边形组成的网格,然后将每个小四边形分割成两个三角形。然后您可以像这样使用GLSL代码:

uniform mat4 uPrj;
attribute vec2 aST;  // Triangles in little squares in range [0,1].
varying vec2 st;
void main(void) {
    vec2 xy=aST*2.0-1.0; // Convert from range [0,1] to range [-1,-1] for vertices.
    gl_Position=uPrj*vec4(xy,0.0,1.0);
    st=aST;
}
上面的代码运行速度足够快,可能甚至比texture2DProj更快,因为片段着色器运行的像素数相同,并且片段着色器可以使用更简单的texture2D方法,无需片段投影

您可以为每个四边形重用aST中的三角形网。下面是我如何用JavaScript制作aST的:

        var nCell = 32;
        var nVertex = nCell * nCell * 6;
        var arST = prog._arST = new Float32Array(nVertex * 2);
        var k = 0;
        for (var j = 0; j < nCell; j++) {
            var j0 = j / nCell;
            var j1 = (j + 1) / nCell;
            for (var i = 0; i < nCell; i++) {
                var i0 = i / nCell;
                var i1 = (i + 1) / nCell;
                arST[k++] = i0;
                arST[k++] = j0;
                arST[k++] = i1;
                arST[k++] = j0;
                arST[k++] = i0;
                arST[k++] = j1;
                arST[k++] = i0;
                arST[k++] = j1;
                arST[k++] = i1;
                arST[k++] = j0;
                arST[k++] = i1;
                arST[k++] = j1;
            }
        }
        gl.bindBuffer(gl.ARRAY_BUFFER, prog._bufferST);
        gl.bufferData(gl.ARRAY_BUFFER, prog._arST, gl.STATIC_DRAW);

嗨,Isogen74,谢谢你的评论。问题是我必须在2D中绘制正方形,因为我只有4个顶点的x和y坐标。它们看起来像是在三维空间中,但它们只是二维形状。我需要使用这些2D坐标来实现透视扭曲效果。你能给我一些关于如何计算纹理坐标的w值的想法吗?