2012-05-17 84 views
8

在使用紋理內存我也碰到過下面的代碼: -紋理內存tex2D基礎

uint f = (blockIdx.x * blockDim.x) + threadIdx.x; 
uint c = (blockIdx.y * blockDim.y) + threadIdx.y; 

uint read = tex2D(refTex, c+0.5f, f+0.5f); 

我的問題是,爲什麼我們添加0.5fcf? 這使我困惑。 謝謝你

回答

14

在圖形中,紋理是描述表面視覺外觀的一組樣本。樣本是一個點。也就是說,它沒有尺寸(與具有物理尺寸的像素相反)。當使用樣本來確定像素的顏色時,每個樣本都位於其對應像素的中心。使用整數座標尋址像素時,給定像素的精確中心將成爲其整個數字座標加上0.5(每個維度)的偏移量。

換句話說,將0.5添加到紋理座標可確保從這些座標讀取時,返回該像素的樣本的確切值。

但是,只有當紋理的filterMode設置爲cudaFilterModeLinear時,從紋理中讀取的值纔會在像素內發生變化。在該模式下,從不在像素的中心的座標讀取返回在給定像素的樣本和相鄰像素的樣本之間插值的值。所以,將0.5加到整數座標有效地否定了cudaFilterModeLinear模式。但是,由於在紋理座標中添加0.5會佔用內核中的週期,因此最好通過將filterMode設置爲cudaFilterModePoint來關閉內插。然後,從像素內的任何座標讀取返回該像素的確切紋理採樣值,因此可以使用整數直接讀取紋理採樣。

當使用cudaFilterModePoint時,如果在計算紋理座標時涉及浮點數學,必須注意確保浮點不準確不會導致紋理座標超出預定目標像素的範圍。

此外,正如評論提到的那樣,代碼中可能存在問題。將0.5f添加到紋理座標意味着正在使用cudaFilterModeLinear模式,但該模式返回一個浮點數,而不是一個int數。

+0

你說紋理座標實際上是指向一個像素中心,所以如果我們可以訪問座標爲0,0的元素,並使用你的方案,我們可以得到1,1像素。 – geek

+0

@ marina.k:我不確定你的意思。答案有問題嗎? –

+0

@Roger達爾謝謝,非常好的答案。 但是,當你說浮點不準確可能會導致座標超出預定目標像素的範圍時,你能詳細說明一下嗎?在精度上浮點意味着什麼? –

0

取決於紋理屬性,tex2D返回的值可能會線性內插。因此,「指數」fc不是整數,而是在每個維度的極限之間的連續值。

在這個例子中有點奇怪的是返回值是一個整數,這將使任何線性插值分段常數。

有關更多詳細信息,請參見CUDA編程指南的第3.2.10節。

+0

「'cudaFilterModeLinear'只對浮點類型的返回值有效。」,所以在這裏我們不能有插值,只有'cudaFilterModePoint' – aland

+0

@aland:這是正確的,但我們不知道是什麼類型'refTex'被聲明爲'float'或'int'或其他。 – Pedro

+0

如果我們使用的座標不是從0.0到1.0,它不能是'cudaFilterModePoint' – geek