簡體   English   中英

如何在屏幕空間中平鋪紋理的一部分?

[英]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.5f(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM