2012-09-13 152 views
5

我想在GLSL中編碼正確的2D仿射紋理映射。正確的glsl仿射紋理映射

說明:

...這個圖像都不是我的目的是正確的。正確(標記爲「正確」)具有我不想要的透視校正。所以這個:Getting to know the Q texture coordinate解決方案(沒有進一步改進)不是我要找的。

我想簡單地「拉伸」紋理內四邊形,這樣的事情:

enter image description here

但是從兩個三角形組成。請提供任何建議(GLSL)?

+1

下面的頂點是上面的頂點還是隻是縮放四邊形的頂點位置? –

+0

縮放,所有座標都是2D的(我只是修改了我的帖子) – velkyel

回答

-2

感謝答案,但嘗試後,我找到了解決辦法。左側

兩個三角形具有根據在右側this和兩個三角形修飾的這個透視校正的版本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)] 

僅直角三角形都採用這種GLSL着色器渲染(左側是固定管道):

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

所以..只有U是透視圖和V是直鏈。

+2

這正是我展示給你的,除非它沒有考慮到很多情況。有六個頂點沒有用處。 – Jessy

6

只要您有梯形,並且其平行邊與局部座標軸之一對齊,就可以很好地工作。我建議玩我的Unity package

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 

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; 
+0

你能寫出什麼頂點包含?我嘗試過'頂點= [Vec2(-1,-1),Vec2(-0.5,1),Vec2(0.5,1),Vec2(1,-1)]''移位位置= [Vec2(0,0), Vec2(2,2),Vec2(1,2),Vec2(1,2),Vec2(2,0)]和[寬度 - 高度= Vec2(2,2),Vec2 (2,2)]。我的片段看起來像:'gl_FragColor = texture2D(colormap,gl_TexCoord [0] .xy/width_heights.xy);'(我必須使用gl_TexCoord)。這根本行不通。 – velkyel

+0

你的vec2s都很好。我認爲我不能爲您提供比Unity項目更有用的任何東西;這就是我現在所知道的。讓我知道你是否需要使用它的幫助,或者如果你能想到其他方式幫助我。我肯定會得到你以後的結果。關鍵是將寬度/高度計算從每個頂點移動到每個「掃描線」。我們能做的最好的是每像素,這是過度的,但這是GPU提供的。 – Jessy

+1

謝謝你的回答。這對我來說非常合適! –

2

我最近設法爲任何類型的四邊形提出了這個問題的通用解決方案。計算和GLSL可能有幫助。在java中有一個工作演示(運行在Android上),但結構緊湊且易讀,應該輕鬆移植到統一或iOS:http://www.bitlush.com/posts/arbitrary-quadrilaterals-in-opengl-es-2-0

+0

不錯,但這不是我想要的。請仔細閱讀第一個問題。第三次四映射不是我想要的。 – velkyel

+0

是的,我的壞,沒有棉花對你需要它沒有透視校正 – keith