[英]How would I tile a section of a texture in screen space?
如果以前曾問過這個問題,請原諒我,我一直在尋找答案,而我所提供的只是基於圖塊的2D游戲的幫助。 X - X
我正在嘗試使用XML文件在Direct3D 9中創建可換皮膚的GUI,該文件具有每個元素的位置以及用於拉伸或平鋪它們的選項。 拉伸是一個非常簡單的過程,但是我一直無法找到一種方法來平鋪紋理的一小部分。 傳統上平鋪紋理時,我只會將UV坐標設置為> 1.0,但是源紋理坐標只會是整個紋理的一小部分,例如0.4到0.5。
我有一種感覺,我確實錯過了一些顯而易見的事情,但是我將如何簡單地平鋪而不是拉伸呢? 我最好的猜測是,它與多於一組的紋理坐標有關,但是從那里,我不確定要去哪里。
該項目當前使用固定功能管道,因此,如果可能的話,我寧願使用它,但是如果那是唯一的方法,我不會拒絕使用着色器的答案。
我了解您只希望平鋪紋理的一部分,對嗎? 然后事情變得復雜了。
假設我們要在u1和u2值之間平鋪u坐標,u1 <u2。
然后我們需要一個函數f(u),這樣
f(0.0) = u1
f(0.5) = (u1+u2)/2
f(0.9999) = u2
f(1.0) = u1
f(1.5) = (u1+u2)/2
f(1.9999) = u2
f(2.0) = u1
and so on...
合適的函數是f(u) = frac(u) * (u2-u1) + u1
v坐標也是如此, f(v) = frac(v) * (v2-v1) + v1
請注意,它是平鋪的,沒有鏡像。 如果需要鏡像,則該函數應該是三角波函數,即t(x) = arcsin(sin(pi*(x-0.5)))/pi+0.5
和f(u) = t(u) * (u2-u1) + u1
。 但是,使用三角函數可能會很昂貴。
我不知道固定管道是否可行,但是您可以在像素着色器(HLSL代碼)中輕松實現:
// float2 tex_coord -> (u,v) from vertex shader, in [0,n] range,
// n - number of repetitions
// float2 tex1, tex2 -> constants, subrange of [0,1] coords that will be tiled
// no mirroring
float4 color = tex2D(sampler, frac(tex_coord) * (tex2-tex1) + tex1);
要么
// mirroring, t(x) = arcsin(sin(pi*(x-0.5)))/pi+0.5
float4 color = tex2D(sampler, t(tex_coord) * (tex2-tex1) + tex1);
編輯:一種更好的計算三角波函數的方法: t1(x) = abs(2(0.5x-floor(0.5x+0.5)))
或t2(x) = abs(2(frac(0.5x+0.5))-1)
(與t1並不完全相同,但適用於非負數)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.