我需要使用極座標將矩形紋理變形爲紋理。傳播光在我的問題,我要說明吧:GLSL ES - 將紋理從矩形映射到極座標,重複執行
我的形象:
,我必須使用着色器變形它是這樣的:
然後我要把它映射到一架飛機上。 我該怎麼做?任何幫助將不勝感激!
我需要使用極座標將矩形紋理變形爲紋理。傳播光在我的問題,我要說明吧:GLSL ES - 將紋理從矩形映射到極座標,重複執行
我的形象:
,我必須使用着色器變形它是這樣的:
然後我要把它映射到一架飛機上。 我該怎麼做?任何幫助將不勝感激!
這並不特別困難。您只需將紋理座標轉換爲極座標,並使用半徑作爲紋理的方向,方位角爲t
方向。
假設你想紋理一個四邊形,並且假設你使用標準texcoords作爲這個,所以左下角的頂點將有(0,0),右上角的(1,1)作爲紋理座標。
所以在片段着色器中,只需要將插入的texcoords(使用tc
)轉換爲極座標。即使中心位於(0.5,0.5),我們必須首先抵消這一點。
vec2 x=tc - vec2(0.5,0.5);
float radius=length(x);
float angle=atan(x.y, x.x);
現在您只需將範圍映射回[0,1]紋理空間。此處的最大半徑將爲0.5,因此您只需使用2*radius
作爲s
座標,並且角度將位於[-pi,pi]中,因此您應將其映射到[0,1]以獲得t
座標。
UPDATE1
有我離開了迄今爲止一些細節。從您的圖像中可以清楚地看到,您不希望內圈映射到紋理。但是這可以很容易地被合併。我只假設這裏有兩個半徑:r_inner
(它是內圓的半徑)和r_outer(它是要在其上映射外部部分的半徑)。讓我爲此畫出一個簡單的片段着色器:
#version ...
precision ...
varying vec2 tc; // texcoords from vertex shader
uniform sampler2D tex;
#define PI 3.14159265358979323844
void main()
{
const float r_inner=0.25;
const float t_outer=0.5;
vec2 x = v_tex - vec2(0.5);
float radius = length(x);
float angle = atan(x.y, x.x);
vec2 tc_polar; // the new polar texcoords
// map radius so that for r=r_inner -> 0 and r=r_outer -> 1
tc_polar.s = (radius - r_inner)/(r_outer - r_inner);
// map angle from [-PI,PI] to [0,1]
tc_polar.t = angle * 0.5/PI + 0.5;
// texture mapping
gl_FragColor = texture2D(tex, tc_polar);
}
現在仍然有一個細節丟失。上面生成的映射會生成位於[0,1]範圍之外的texcoords,用於圖像中任何位置。但紋理採樣在這裏不會自動給黑色。最簡單的解決方案是在紋理的左右兩端添加黑色像素,並將紋理的GL_TEXTURE_WRAP_S
模式設置爲GL_CLAMP_TO_EDGE
。這樣,你幾乎可以免費得到黑色。另一種方法是在着色器中添加一個布爾值,並檢查tc_polar.s
是否低於0或高於1.
我找到了上述着色器的擴展版本:polarpixellate glsl。這篇文章適合那些想要更靈活着色的人。
你能分享完整的着色器代碼嗎? – Nolesh 2014-09-22 12:49:38
@Nolesh:我更新了我的答案。 – derhass 2014-09-22 18:50:37
你知道如何改變這個着色器來創建段的結果嗎?所以,我需要重複給定的紋理,而不是拉伸。 – Nolesh 2014-09-23 13:18:46