WebGL纹理像素值修改

时间:2016-02-03 07:35:30

标签: javascript textures webgl

我正在尝试修改纹理的像素值。 例如:我想将纹理设置得更透明。 我使用gl = canvas.getContext(“webgl”)和gl.readPixels()来获取纹理的像素值。

代码如下:

  var framebuffer = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, sTexture, 0);

  if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE)
  {
      var sTextureSize = sTexture.image.width * sTexture.image.height * 4;    // r, g, b, a
      var pixels = new Uint8Array( sTextureSize );
      gl.readPixels( 0, 0, sTexture.image.width, sTexture.image.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels );

      for( var i=0 ; i<sTextureSize ; i+=4 )
      {
          if( pixels[i+3] > 0 )
          {
              pixels[i+3] = Math.min( 255, pixels[i+3]*0.5 );     // set half alpha
          }
      }

  }

  gl.deleteFramebuffer(framebuffer);

完成此过程后,我的纹理透明度似乎没有改变。

我知道我可以通过着色器代码修改纹理alpha值,但是可以直接编辑纹理像素值并立即显示效果吗?

感谢您的建议。

1 个答案:

答案 0 :(得分:1)

您必须使用gl.texImage2D

重新上传更改
  var framebuffer = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, sTexture, 0);

  if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE)
  {
      var sTextureSize = sTexture.image.width * sTexture.image.height * 4;    // r, g, b, a
      var pixels = new Uint8Array( sTextureSize );
      gl.readPixels( 0, 0, sTexture.image.width, sTexture.image.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels );

      for( var i=0 ; i<sTextureSize ; i+=4 )
      {
          if( pixels[i+3] > 0 )
          {
              pixels[i+3] = Math.min( 255, pixels[i+3]*0.5 );     // set half alpha
          }
      }

      // upload changes
      gl.bindTexture(gl.TEXTURE_2D, sTexture);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 
                    sTexture.image.width, sTexture.image.height, 0,
                    gl.RGBA, gl.UNSIGNED_BYTE, pixels);
  }

  gl.deleteFramebuffer(framebuffer);

gl.readPixels只是读取纹理的副本。您修改副本。然后,您必须将该副本上载回纹理。

注意:如果您使用mips,则需要致电gl.generateMipmap或手动更新mips,如果他们希望他们考虑您的更改。