2015-04-24 40 views
0

我正在嘗試使用頂點着色器和片段着色器創建四角透視效果。如何在使用opengl es 2.0在glsl中進行透視變形時正確映射紋理

我設置頂點位置信息來繪製像形狀的透視圖,然後映射我的紋理。但不知何故紋理未正確映射。

下面是兩張照片向您展示問題。

enter image description here

enter image description here

我找到這個posttexture2DProj也許正確的答案一定的相關信息,但我不太明白它是如何工作的。我試圖做這樣的事情,

varying lowp vec4 TexCoordOut; 
    uniform sampler2D Texture; 

    void main(void) { 
     gl_FragColor = texture2DProj(Texture, TexCoordOut); 
    } 

而對於TexCoordOut

{1, 0, 0, 1} 
{1, 1, 0, 1} 
{0, 1, 0, 1} 
{0, 0, 0, 1} 

傳遞到頂點着色器,並改變成片段着色器。但結果是一樣的。

我只知道如何使用texture2Dvec2,我怎麼能得到我的紋理座標的其他兩個組件與texture2DProj一起使用?

回答

0

我懷疑問題在於你的輸入座標是渲染一個二維形狀,而不是三維形狀(即,你對所有4個頂點都有一個恆定的Z值)。

不是渲染2D形狀,而是渲染以3D形式傾斜的正方形,並且變化的插值將爲您進行透視正確分割。然後您可以使用正常的texture2D()操作。

你可能不希望在這種情況下使用投影紋理 - 你可以 - 但它是不必要的複雜的(你仍然需要爲紋理座標生成一個合適的「w」值來獲得透視分割工作,所以你可能會以及每個頂點做這件事,並使用不同的插值器來完成繁重的工作)。

+0

嗨Isogen74,感謝您的評論。事情是我必須在2D中繪製正方形,因爲我只有4個頂點的'x'和'y'座標。它們看起來像是在3D空間中,但它們只是2D形狀。我需要使用這些2D座標來實現透視扭曲效果。你能給我一些關於如何計算紋理座標的'w'值的想法嗎? –

0

如果你真的想使用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);