在使用纹理内存时,我遇到了以下代码: -
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.5f
添加到c
和f
?这让我感到困惑..谢谢你
在图形中,纹理是一组描述表面视觉外观的样本。样本是一个点。也就是说,它没有尺寸(与具有物理尺寸的像素相反)。使用样本确定像素的颜色时,每个样本都位于其对应像素的精确中心。当使用整数坐标寻址像素时,给定像素的精确中心变为其整数坐标加上0.5的偏移(在每个维度中)。
换句话说,将0.5添加到纹理坐标可确保在从这些坐标读取时,返回该像素的样本的精确值。
但是,只有当纹理的filterMode
设置为cudaFilterModeLinear
时,从纹理读取的值才会在像素内变化。在该模式中,从不在像素的精确中心的坐标读取返回在给定像素的样本和相邻像素的样本之间插值的值。因此,将0.5添加到整数坐标有效地否定了cudaFilterModeLinear
模式。但是,由于在纹理坐标中添加0.5会占用内核中的循环,因此最好通过将filterMode
设置为cudaFilterModePoint
来简单地关闭插值。然后,从像素内的任何坐标读取将返回该像素的精确纹理样本值,因此,可以使用整数直接读取纹理样本。
使用cudaFilterModePoint
时,如果计算纹理坐标涉及任何浮点数学,则必须注意确保浮点不准确不会导致纹理坐标落在预期目标像素的范围之外。
此外,正如评论中提到的,您的代码可能存在问题。将0.5f添加到纹理坐标意味着正在使用cudaFilterModeLinear
模式,但该模式返回浮点数,而不是int。
根据纹理属性,tex2D
返回的值可以线性插值。在这种情况下,“指数”f
和c
不应该是整数,而应该是每个维度的极限之间的连续值。
在这个例子中有点奇怪的是返回值是一个整数,无论如何它将使任何线性插值分段常数。
有关更多详细信息,请参见“CUDA编程指南”的第3.2.10节。