【发布时间】:2015-02-11 02:47:18
【问题描述】:
我正在使用 C++ 和 HLSL,需要将我的纹理坐标换行,以便纹理平铺在三角形上。
坐标被“包裹”到0-1范围后,它们会被旋转,所以我不能简单地使用纹理采样器的AddressU和AddressV属性设置来包裹,因为它们需要被包裹然后旋转,所以它不能在采样器内部完成。
这里的解决方法很简单,只用纹理坐标的小数部分就可以了。
下面是一个像素着色器的例子,它将纹理平铺 36 次 (6 * 6):
input.tex *= 6.0f; //number of times to tile ^ 2
input.tex = frac(input.tex); //wraps texCoords to 0-1 range
return shaderTexture.Sample(SampleType, input.tex);
这确实会平铺纹理,但会在纹理包裹的边界处产生问题。瓷砖必须均匀地分成它们正在展示的空间,否则会在寄宿生相遇的地方形成接缝。我绘制纹理的正方形是 800x600 像素,因此平铺 5 会平铺,但 6 则不会,并且会导致沿 Y 轴出现接缝。
我尝试使用模运算符input.tex = input.tex % 1 来包装坐标,但得到完全相同的结果。我还尝试更改纹理过滤方法以及 AddressU 和 AddressV 属性以及无数不同的调试方法。
我很幸运地使用了这段代码。如果x 坐标太高则设置为 0,如果太低则设置为 1。
input.tex *= 6.0f;
input.tex = frac(input.tex);
if (input.tex.x > 0.999f) input.tex.x = 0;
if (input.tex.x < 0.001f) input.tex.x = 1;
return shaderTexture.Sample(SampleType, input.tex);
这只是解决了某些地方的问题,所以它绝对不是一个解决方案。
这是一张显示纹理的图片(左)和手动包裹时的样子(右)。您可以看到,并非寄宿生接触的所有地方都有此错误。
我也尝试过不将纹理坐标更改为 0-1 范围并将它们围绕每个图块的中心而不是 (0.5, 0.5) 旋转,但我得到了相同的结果。此外,我的纹理坐标完全独立于顶点,并在像素着色器中计算。
我所看到的与此问题有关的任何事情都与一个像素的高值和下一个像素的低值有关,例如 u = 0.95 和下一个像素 u = 0.03,这会导致它向后插值穿过纹理。但是当我旋转我的纹理坐标时,什么都没有改变。即使每个图块都应用了随机旋转。在这种情况下,边缘有各种不同的值相互接壤,不仅仅是左侧的高值和右侧的低值,而且出现接缝的区域永远不会改变。
【问题讨论】: