-
Notifications
You must be signed in to change notification settings - Fork 177
Open
Description
复现代码
放大一个checker texture并输出图片:
const int N = 64;
Bitmap texture(N, N);
for (int y = 0; y < N; ++y)
for (int x = 0; x < N; ++x) {
uint32_t color = (x + y) & 1 ? 0xff000000 : 0xffffffff;
texture.SetPixel(x, y, color);
}
const int W = 3072, H = 2048;
Bitmap output(W, H);
for (int y = 0; y < H; ++y)
for (int x = 0; x < W; ++x) {
float u = (x + 0.5f) / W, v = (y + 0.5f) / H;
output.SetPixel(x, y, texture.Sample2D(u, v));
}
output.SaveFile("output.bmp");发现checker texture比预期的位置向左、上平移了一个网格,并在图片的右、下边沿导致拖影。

可能的原因和解决办法
- 现有的代码中,
Bitmap::SampleBilinear方法接收的参数值为(x = u * _w + 0.5f, y = v * _h + 0.5f)。 - 所以,这两个参数的取值范围是
0.5 <= x <= _w + 0.5, 0.5 <= y <= _h + 0.5。 - 获得四个像素坐标的位运算等价于:
x1 = floor(x), y1 = floor(y), x2 = ceil(x), y2 = ceil(y)。 - 可以看出,取样时图像的左、上边永远不会被裁切,而图像右、下边可能被裁切。
如果减去一个像素的偏移,把Bitmap::SampleBilinear开头部分的代码修改为:
int32_t x1 = Between(0, _w - 1, (fx >> 16) - 1);
int32_t y1 = Between(0, _h - 1, (fy >> 16) - 1);
int32_t x2 = Between(0, _w - 1, fx >> 16);
int32_t y2 = Between(0, _h - 1, fy >> 16);发现上述问题不再出现。
Metadata
Metadata
Assignees
Labels
No labels