【问题标题】:2D tile based game, shows gaps between the tile sprites when I zoom in with the camera?基于 2D 瓷砖的游戏,当我用相机放大时显示瓷砖精灵之间的间隙?
【发布时间】:2011-05-28 16:16:18
【问题描述】:

我正在使用 D3DXSPRITE 方法将我的地图图块绘制到屏幕上,我只是添加了一个缩放功能,当您按住向上箭头时会放大,但注意到您现在可以看到图块之间的间隙,这是一些屏幕截图

每个图块的正常尺寸 (32x32)

放大(您可以看到瓷砖之间的白色间隙)

缩小(甚至更糟!)

这是我用来翻译和缩放世界的代码片段。

D3DXMATRIX matScale, matPos;

D3DXMatrixScaling(&matScale, zoom_, zoom_, 0.0f);
D3DXMatrixTranslation(&matPos, xpos_, ypos_, 0.0f);

device_->SetTransform(D3DTS_WORLD, &(matPos * matScale));

这是我绘制的地图,(瓦片位于瓦片矢量的矢量中..我还没有完成剔除)

LayerInfo *p_linfo = NULL;
  RECT rect = {0};
  D3DXVECTOR3 pos;
  pos.x = 0.0f;
  pos.y = 0.0f;
  pos.z = 0.0f;

  for (short y = 0; 
    y < BottomTile(); ++y)
  {
    for (short x = 0; 
          x < RightTile(); ++x)
    {
      for (int i = 0; i < TILE_LAYER_COUNT; ++i)
      {
        p_linfo = tile_grid_[y][x].Layer(i);

        if (p_linfo->Visible())
        {
          p_linfo->GetTextureRect(&rect);

          sprite_batch->Draw(
            p_engine_->GetTexture(p_linfo->texture_id), 
            &rect, NULL, &pos, 0xFFFFFFFF);
        }
      }
      pos.x += p_engine_->TileWidth();
    }
    pos.x = 0;
    pos.y += p_engine_->TileHeight();
  }

【问题讨论】:

  • 如果改变背景颜色,线条是否会改变颜色?知道实际上排除了您的纹理或过滤没有发生任何事情可能会很有趣。
  • 你确实需要使用着色器和 ID3DXEffect,而不是固定功能。
  • 线条不会改变颜色,只是看起来是白色的,我试过清晰的红色、蓝色、黑色,看起来都一样。
  • 我来看看 d3dxeffect

标签: c++ direct3d direct3d9


【解决方案1】:

你的纹理索引是错误的。 0,0,32,32 不是正确的值 - 它应该是 0,0,31,31。从零开始的 256 像素纹理图集的索引将产生 0 到 255 的值,而不是 0 到 256,并且 32x32 纹理应该产生 0,0,31,31。在这种情况下,错误像素的颜色取决于右侧和底部的下一个纹理的颜色。

【讨论】:

  • 接缝是右边和底部纹理的颜色!但我尝试返回 0,0,31,31 的矩形,现在我有 1 个像素的间隙。为什么我只能在放大或缩小时才能看到接缝?如果我截屏并检查油漆,每个图块现在是 31 像素宽并且缺少一列像素
  • @Kaije:很可能是您的布局代码无法将它们定位在屏幕上。
  • 每个图块在循环中相隔 32 像素,并且使用 0,0,31,31,每个图块的每一侧都有 1 个像素的间隙,当我截图并放大时,我计算像素1 个图块,其 31x31 像素,缺少一些纹理
  • 我认为它需要 0-32,因为通常当你循环某些东西时,你确实喜欢 (i=0; i
  • @Kaije:您应该尝试单独加载纹理并为矩形传递 NULL,看看这是否解决了 ahnd 的问题
【解决方案2】:

这就是放大和缩小的问题。您的纹理应该有不可见的边界,其中填充了部分相邻纹理。然后放大和缩小滤镜将使用该边框来计算边缘像素的颜色,而不是默认(白色)颜色。

我想是的。

【讨论】:

  • 我认为这是真正的答案。纹理插值访问多个纹素。在边界上,一些纹素没有值,这会导致这些伪影。 Mipmapping 加剧了这些问题。但是你的纹理看起来很简单,也许你可以将模式设置为重复。
【解决方案3】:

我在纹理映射方面也遇到了类似的问题。对我有用的是更改采样器状态描述中的纹理地址模式;纹理地址模式用于控制 direct3d 对 ([0.0f, 1.0f]) 范围之外的纹理坐标所做的操作:我将 ADDRESS_U、ADDRESS_V、ADDRESS_W 成员更改为 D3D11_TEXTURE_ADDRESS_CLAMP,它基本上钳制了所有超出范围的值纹理坐标在 [0.0f, 1.0f] 范围内。

【讨论】:

    【解决方案4】:

    经过长时间搜索和测试人员解决方案,我发现此规则是我读过的最完整的规则。

    pixel-perfect-2d from Official Unity WebSite

    plus 根据我自己的经验我发现如果 sprite PPI 为 72(例如),您应该尝试为该图像使用更多 PPI(可能是 96 或更多)。它实际上使精灵更密集,并且没有空间让白色间隙出现。

    【解决方案5】:

    欢迎来到浮点世界。这些差距是由于使用浮点数的缺陷而存在的。

    在进行浮点数学运算时要非常小心,也许可以改善这种情况,但除非你从地形中制作出一个完整的网格,否则这些接缝会存在。

    给定视图和投影矩阵以及顶点位置的光栅化器略有偏差。你也许可以在这方面有所改进,但我不知道你会取得多大的成功。

    您可以只索引构成地形的可见顶点,而不是绘制不同的四边形,而是使用纹理平铺技术在上面绘制不同的东西。我相信这不会给你带来丑陋的接缝,因为在那种情况下,技术上是没有接缝的。

    【讨论】:

    • 这不是 FP 缺陷,它太规律了。
    • @DeadMG 嗯,不。我敢打赌,这是光栅化器中发生的舍入问题。鉴于事情是如何设置的。您可以尽量减少此类问题的可见性,但它们会一直存在。
    • 舍入问题不会定期产生影响,因为浮点表示的分布不均等。伪影将或多或少地出现在较低的范围内。
    • 好的,但是如果视图和/或投影矩阵设置不当怎么办?
    • 我在 Unity 中遇到了同样的问题。我很确定它的 fp 缺陷。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-20
    相关资源
    最近更新 更多