【问题标题】:Texture repeating and clamping in shader着色器中的纹理重复和钳位
【发布时间】:2013-01-27 20:57:59
【问题描述】:

我有以下片段和顶点着色器,我在其中重复纹理:

//Fragment
vec2 texcoordC = gl_TexCoord[0].xy;
texcoordC *= 10.0;
texcoordC.x = mod(texcoordC.x, 1.0);
texcoordC.y = mod(texcoordC.y, 1.0);
texcoordC.x = clamp(texcoordC.x, 0.0, 0.9);
texcoordC.y = clamp(texcoordC.y, 0.0, 0.9);
vec4 texColor = texture2D(sampler, texcoordC);
gl_FragColor = texColor;

//Vertex
gl_TexCoord[0] = gl_MultiTexCoord0;
colorC = gl_Color.r;
gl_Position = ftransform();

添加:在此过程之后,我获取纹理坐标并使用纹理包:

vec4 textureGet(vec2 texcoord) {
    // Tile is 1.0/16.0 part of texture, on x and y
    float tileSp = 1.0 / 16.0;

    vec4 color = texture2D(sampler, texcoord);
    // Get tile x and y by red color stored
    float texTX = mod(color.r, tileSp);
    float texTY = color.r - texTX;
    texTX /= tileSp;
    // Testing tile
    texTX = 1.0 - tileSp;
    texTY = 1.0 - tileSp;

    vec2 savedC = color.yz;
    // This if else statement can be ignored. I use time to move the texture. Seams show without this as well.
    if (color.r > 0.1) {
        savedC.x = mod(savedC.x + sin(time / 200.0 * (color.r * 3.0)), 1.0);
        savedC.y = mod(savedC.y + cos(time / 200.0 * (color.r * 3.0)), 1.0);
    } else {
        savedC.x = mod(savedC.x + time * (color.r * 3.0) / 1000.0, 1.0);
        savedC.y = mod(savedC.y + time * (color.r * 3.0) / 1000.0, 1.0);
    }
    vec2 texcoordC = vec2(texTX + savedC.x * tileSp, texTY + savedC.y * tileSp);

    vec4 res = texture2D(texturePack, texcoordC);
    return res;
}

但是,我在显示接缝(似乎是 1 像素)时遇到了一些麻烦。如果我省略 texcoord *= 10.0 ,则不会显示(或几乎不显示)接缝,如果我将其留在其中,它们会出现。我钳制坐标(甚至尝试低于 1.0 和大于 0.0)无济于事。我强烈地感觉它是某个地方的舍入错误,但我不知道在哪里。 添加:需要注意的是,在实际情况下,我将 texcoordC x 和 y 转换为 8 位浮点数。我认为原因就在这里;我在上面添加了另一个着色器来描述这一点。

我展示的情况在现实中要复杂一些,所以我在着色器之外没有用处(!)。我添加了上一个问题,该问题对案例进行了一些解释。

编辑:如您所见,自然纹理跨度除以 10,纹理重复(10 次)。接缝出现在每个重复纹理的边界处。我还添加了一个屏幕截图。接缝是非常细的线(~1pixel)。图片是从屏幕截图中截取的,未按比例缩放。重复纹理为 16x16,总共 256 个子像素。

编辑:这是this question 的后续问题,尽管此处应包含所有必要信息。

最后一张图片没有添加时间。

【问题讨论】:

  • mod(value, 1.0) 会产生[0, 1.0[,所以clamp(value, 0.0, 0.9) 总是会引入不连续性。
  • 我后来加了夹子;我想它也不会造成接缝。
  • 你是如何为你正在绘制的对象设置纹理坐标的?
  • “接缝”是什么意思?你在哪里看到这些接缝?你想用这个渲染什么?
  • @user1118321:纹理坐标始终为 0..1。正如你所看到的重复作品。

标签: opengl glsl


【解决方案1】:

查看 UV 坐标的渲染,它们正在被过滤,这将导致与您上一个问题相同的问题,但规模较小。正在发生的事情是,通过在两个不连续值之间的点(即纹理坐标包裹的两个相邻点)对 UV 坐标纹理进行采样,您会得到一个不在纹理右侧的插值值。因此,纹理图块之间的边界是来自该图块各处的一堆像素。

您需要在屏幕像素和捕获的 UV 值之间获得 1:1 的映射。使用最接近的采样可能会帮助您解决问题,但如果您首先拥有正确的纹理和像素坐标,则应该可以不使用它。

其次,您可能会发现由于您执行纹理图集查找的方式而产生出血效果,因为您没有考虑对纹素进行采样的方式。如果您使用任何 mipmapping,这将被放大。理想情况下,您需要一个边框,并且可能需要对坐标进行一些按摩以解决半纹素偏移。但是,我认为这不是您在这里看到的主要问题。

【讨论】:

  • 我没有注意到过滤,我以为没有过滤。但是,我之前确实想出了同样的方法,使用最近的而不是线性的,但没有帮助。但是您的回答确实为我指明了正确的方向,因此我将对此进行更多研究。感谢您的帮助!
  • 解决了,显然我没有在正确的地方设置最近。
  • 我通过在第一个片段着色器中乘以 11.0 而不是 10.0 解决了半纹素查找问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
  • 2020-04-16
  • 2013-02-20
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多