如何使用 texelFetch 在着色器上不过滤的一维纹理

How to use 1D texture with no filtering on the shader with texelFetch

我想将一堆浮点数传递给片段着色器,并通过索引访问它们。

这个答案中提到的基本上是 1D Textures 方法:Passing a list of values to fragment shader

我试试这个:

javascript code

  gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  const data = new Uint8Array([
    255, 64, 192,
    0, 192, 0
  ]);

  let texture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D,
                0,
                gl.R8,
                3,
                2,
                0,
                gl.RED,
                gl.UNSIGNED_BYTE,
                data);

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, texture);

我在碎片着色器中访问这个制服:

uniform sampler2D u_texture;

void main() {    
  vec2 trans = texelFetch(u_texture, ivec2(0, 0), 0);
}

我使用 glTexImage2D 因为我看到了一个例子, 这部分有效,但有两个问题:

我想摆脱所有过滤选项 gl.texParameteri 因为我不需要它们。但是如果我删除那些我就得不到数据。

texelFetch 方法 returns 值在 [1, 0] 范围内(例如:1 表示 255)。为什么会这样?

基本上我需要一个上述方法的例子。

I want to get rid of all the filtering options gl.texParameteri because I don't need them. But if I delete those I don't get the data.

纹理参数存储在纹理对象中。参数TEXTURE_MIN_FILTER的初始值为NEAREST_MIPMAP_LINEARTEXTURE_MAG_FILTERLINEARTEXTURE_WRAP_S分别为TEXTURE_WRAP_TREPEAT.
如果你想要不同的参数值,那么你必须明确地设置它们(对于每个纹理对象)。没有办法。

在您的情况下,问题是参数 TEXTURE_MIN_FILTER 的初始值(如上所述,它是 NEAREST_MIPMAP_LINEAR)。
如果缩小过滤器需要 mipmap(不是 NEAREST 也不是 LINEAR),但纹理没有 mipmap,则纹理不是 "mipmap complete".
请注意,如果纹理不完整,纹理元素获取的结果是 (0, 0, 0, 1)。参见 WebGL 2.0 - 5.12 Texel Fetches


This texelFetch method returns values in the range [1, 0] (eg: 1 for 255). Why does that happen?

这是由用于指定像素数据 (gl.texImage2D) 的像素格式引起的。

格式、类型组合 gl.REDgl.UNSIGNED_BYTE 指定了 Normalized Integer 格式。对于无符号归一化整数(例如 UNSIGNED_BYTEUNSIGNED_SHORTUNSIGNED_INT),整型数据类型的整个范围映射到浮点范围 [0, 1],并映射到范围 [ -1, 1] 用于带符号的归一化整数(例如 BYTESHORTINT)。


WebGL 2.0 (respectively OpenGL ES 3.0) there is the possibility to specify the image format by the combination gl.RED_INTEGER, gl.UNSIGNED_BYTE, which specifies an integral pixel format and corresponds to the internal image format R8UI (see WebGl 2.0 - 3.7.6 Texture objects):

gl.texImage2D(gl.TEXTURE_2D,
              0,
              gl.R8UI,
              3,
              2,
              0,
              gl.RED_INTEGER,
              gl.UNSIGNED_BYTE,
              data);