【问题标题】:interpolated texture coordinates插值纹理坐标
【发布时间】:2012-05-04 14:24:09
【问题描述】:

我正在开发一个 OpenGL ES fluid simulation,它使用纹理贴图来保存网格值。我需要遍历模仿以下循环的网格:

for (int r = 0; r < 128; r++)
   for (int c = 0; c < 128; c++)
      process grid element at (c,r)

要遍历网格,我只是填充一个四边形,这会导致为每个片段调用我的片段程序。纹理坐标 (0,0), (1,0), (0,1), (1,1) 与顶点 (-1,-1), (+1,-1), (-1,+1), (+1,+1) 相关联,我将四边形(作为三角形条带)渲染为 128x128附加到 FBO 的纹理贴图如下:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, texFrameBuffer);
glViewport(0, 0, TEX_IMAGE_WIDTH, TEX_IMAGE_HEIGHT); // 128 x 128

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glEnableVertexAttribArray(positionAttr);
glVertexAttribPointer(positionAttr, 2, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);
glEnableVertexAttribArray(texCoordAttr);
glVertexAttribPointer(texCoordAttr, 2, GL_FLOAT, GL_FALSE, 0, 0);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

顶点着色器仅通过未修改的位置和纹理坐标。为了了解正在生成的纹理坐标,我决定将纹理坐标捕获到图像中。片段程序将其给定的 2D 纹理坐标分配给输出颜色的红色和绿色通道:

varying vec4 texCoord;
void main() {
  gl_FragColor = vec4(texCoord.st,0,1);
}

然后我使用glGetTexImage() 将纹理图像读回客户端空间。 以下是图像中每个像素生成的纹理坐标(s,t)的示例:

(column, row) = [s, t] -> (128*s, 128*t)

(0,0) = [0.00392157, 0.00392157] -> (0,0)
(1,0) = [0.01176471, 0.00392157] -> (1,0)
(2,0) = [0.01960784, 0.00392157] -> (2,0)
(3,0) = [0.02745098, 0.00392157] -> (3,0)
(4,0) = [0.03529412, 0.00392157] -> (4,0)
(5,0) = [0.04313726, 0.00392157] -> (5,0)
(6,0) = [0.05098040, 0.00392157] -> (6,0)
(7,0) = [0.05882353, 0.00392157] -> (7,0)
(8,0) = [0.06666667, 0.00392157] -> (8,0)
(9,0) = [0.07450981, 0.00392157] -> (9,0)
(10,0) = [0.08235294, 0.00392157] -> (10,0)
<snip>
(125,0) = [0.98039222, 0.00392157] -> (125,0)
(126,0) = [0.98823535, 0.00392157] -> (126,0)
(127,0) = [0.99607849, 0.00392157] -> (127,0)
(0,1) = [0.00392157, 0.01176471] -> (0,1)
(1,1) = [0.01176471, 0.01176471] -> (1,1)
(2,1) = [0.01960784, 0.01176471] -> (2,1)
<snip>
(124,127) = [0.97254908, 0.99607849] -> (124,127)
(125,127) = [0.98039222, 0.99607849] -> (125,127)
(126,127) = [0.98823535, 0.99607849] -> (126,127)
(127,127) = [0.99607849, 0.99607849] -> (127,127)

现在回答问题。我试图理解这些生成的坐标。 神奇的值0.00392157(0.5 * 1/127.5)。我知道 0.5 因子是预先添加的舍入值,但为什么是 127.5? (0.5 * 1/128.0) 会更有意义吗?谁能解释一下这些坐标?我只想从纹理坐标生成整数网格坐标(OpenGL ES 中没有sampler2Drect)。

【问题讨论】:

    标签: opengl-es grid texture-mapping


    【解决方案1】:

    我总是为此苦恼,所以让我们看看我能不能解释一下。

    想象一下您的网格中的一行。在下图中,我已为该行中的每个片段 (0-127) 编号。我也在像素下方放置了一些纹理坐标。请注意,最左边是 0.0,最右边是 1.0。

     +-----------+-----------+-----------+-----------+---    ---+-----------+
     |           |           |           |           |          |           |
     |           |           |           |           |          |           |
     |     0     |     1     |     2     |     3     |   . . .  |    127    |
     |           |           |           |           |          |           |
     |           |           |           |           |          |           |
     +-----------+-----------+-----------+-----------+---    ---+-----------+
     ^           ^           ^           ^                      ^           ^
     |           |           |           |                      |           |
     |           |           |           |                      |           |
    0/128       1/128       2/128       3/128                127/128     128/128
    

    当渲染器想要对片段进行纹理处理时,它使用片段中心的纹理坐标——数字所在的位置。请注意,片段 0 的中心位于 0/128(又名 0)和 1/128(又名 .0078125)之间。那是 1/256(又名 .00390625)。

    所以,我认为公式会更好地表达为:

    coordinate = (pixelId + 0.5) / 128
    

    这里有一些 python 可以得到与你的答案相似的:

    for i in range(128):
       print (0.5 + i) / 128
    
    
    0.00390625
    0.01171875
    0.01953125
    0.02734375
    0.03515625
    0.04296875
    ...
    0.97265625
    0.98046875
    0.98828125
    0.99609375
    

    我怀疑我的结果和您的结果之间的差异与您的值被压缩到一个 [8 位] 颜色通道以从着色器返回它们的事实有关。

    我希望这会有所帮助。

    【讨论】:

    • 你能把句子“想象一下你的 128 排在你的网格中”吗?请问?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多