Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitmap::Sample2D方法有一个像素的偏差 #4

Open
yunhao-qian opened this issue Aug 24, 2020 · 0 comments
Open

Bitmap::Sample2D方法有一个像素的偏差 #4

yunhao-qian opened this issue Aug 24, 2020 · 0 comments

Comments

@yunhao-qian
Copy link

复现代码

放大一个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比预期的位置向左、上平移了一个网格,并在图片的右、下边沿导致拖影。
output

可能的原因和解决办法

  • 现有的代码中,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);

发现上述问题不再出现。

LonelySilen pushed a commit to LonelySilen/RenderHelp that referenced this issue Jan 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant