[英]Implementing trapezoidal sprites in LibGDX
我正在嘗試為一個簡單的2D游戲創建程序動畫引擎,這將使我能夠從少量圖像中創建外觀精美的動畫(類似於這種方法,但適用於2D: http : //www.gdcvault.com / play / 1020583 / Animation-Bootcamp-An-Indie-Approach )
目前,我有一些關鍵幀保存着不同動畫對象的數據,這些關鍵幀是表示以下內容的float數組:
translateX,translateY,scaleX,scaleY,旋轉(度)
我想將skewX,skewY,taperTop和taperBottom添加到此列表中,但是我無法正確渲染它們。
這是我嘗試在精靈的頂部實現錐形以使其具有梯形形狀的嘗試:
float[] vert = sprite.getVertices();
vert[5] += 20; // top-left vertex x co-ordinate
vert[10] -= 20; // top-right vertex x co-ordinate
batch.draw(texture, vert, 0, vert.length);
不幸的是,這會產生一些奇怪的紋理變形。
我對Google有點了解,然后環顧了StackOverflow,發現了這一點,這似乎是我遇到的問題:
http://www.xyzw.us/~cass/qcoord/
但是我不理解它背后的數學(s,t,r和q是什么?)。
有人可以解釋一下嗎?
基本上,四邊形與矩形的相似程度越小,由於在形狀上線性插入紋理坐標的效果,外觀越差。 組成四邊形的兩個三角形被拉伸為不同的大小,因此線性插值使接縫非常明顯。
對於片段着色器處理的每個片段,線性插入每個頂點的紋理坐標。 通常將紋理坐標存儲為已划分對象的大小,因此坐標在0-1的范圍內,與紋理的邊緣相對應(超出此范圍的值將被夾緊或包裹)。 通常,這也是任何3D建模程序如何導出網格的方式。
對於梯形,我們可以通過將紋理坐標乘以寬度,然后在線性插值后將寬度從紋理坐標后除以來限制變形。 這就像彎曲兩個三角形之間的對角線,以使它的斜率在梯形更寬的邊角處更加水平。 這是一張有助於說明它的圖像。
紋理坐標通常表示為具有分量U和V(也稱為S和T)的2D向量。但是,如果您想將尺寸除以這些分量,則需要在插值后再分割一個分量,這就是所謂的Q分量。 (如果您在3D紋理而不是2D紋理中查找某些內容,則P分量將用作紋理中的第三個位置)。
現在來了困難的部分... libgdx的SpriteBatch不支持Q組件所需的額外頂點屬性。 因此,您可以克隆SpriteBatch並仔細進行修改,使其在texCoord屬性中具有額外的組件,或者可以嘗試重新利用現有的color屬性,盡管它以無符號字節的形式存儲。
無論如何,您都需要預先按寬度划分的紋理坐標。 一種簡化此方法的方法是,不使用四邊形的實際四邊形大小,而是獲取梯形的頂部和底部寬度的比率,因此我們可以將頂部的寬度視為1,因此將其保留單獨。
float bottomWidth = taperBottom / taperTop;
然后,您需要修改TextureRegion的現有紋理坐標,以將它們預先乘以寬度。 由於上述簡化,我們可以將梯形的頂點留在頂部,但是兩個窄邊頂點的U和V坐標需要乘以bottomWidth
。 每次更改TextureRegion或其中一個錐度值時,都需要重新計算它們並將其放入頂點數組。
在頂點着色器中,您需要將額外的Q分量傳遞給片段着色器。 在片段着色器中,我們通常使用大小划分的紋理坐標來查找紋理顏色,如下所示:
vec4 textureColor = texture2D(u_texture, v_texCoords);
但是在我們的情況下,我們仍然需要除以那個Q分量:
vec4 textureColor = texture2D(u_texture, v_texCoords.st / v_texCoords.q);
但是,這會導致讀取依賴的紋理,因為我們在將向量傳遞到紋理函數之前對其進行了修改。 GLSL提供了一個自動執行上述操作的功能(並且我認為不會導致依賴的紋理讀取):
vec4 textureColor = texture2DProj(u_texture, v_texCoords); //first two components automatically divided by last component
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.