简体   繁体   中英

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

I want to pass a bunch of floats to the fragment shader, and access them by index.

Basically 1D Textures method mentioned in this answer: Passing a list of values to fragment shader

I try this:

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);

I access this uniform in frag shader:

uniform sampler2D u_texture;

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

I use glTexImage2D because I saw an example of that, This partially works, but has two problems:

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.

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

Basically I need an example of the mentioned method.

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.

The texture parameters are stored in the texture object. The initial value of the parameter TEXTURE_MIN_FILTER is NEAREST_MIPMAP_LINEAR , for TEXTURE_MAG_FILTER it is LINEAR and for TEXTURE_WRAP_S respectively TEXTURE_WRAP_T it is REPEAT .
If you want different values for parameters, then you've to set them explicitly (for each texture object). There is no way around.

In your case the issue is the initial value of the parameter TEXTURE_MIN_FILTER (as mentioned above it is NEAREST_MIPMAP_LINEAR ).
If the minification filter requires a mipmap (not NEAREST and not LINEAR ), but the texture doesn't have mipmaps, then the texture is not "mipmap complete".
Note, the result of of a texel fetch is (0, 0, 0, 1), if a texture is not complete. See 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?

This is cause by the pixel format which is used to specify the pixel data ( gl.texImage2D ).

The format, type combination gl.RED , gl.UNSIGNED_BYTE specifies a Normalized Integer format. The full range of the integral data type is mapped to the floating point range [0, 1] for unsigned normalized integers (such as UNSIGNED_BYTE , UNSIGNED_SHORT , UNSIGNED_INT ) and to the range [-1, 1] for signed normalize integers (such as BYTE , SHORT , INT ).


In 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM