WebGL 纹理像素值修改
WebGL texture pixel value modify
我正在尝试修改纹理的像素值。
例如:我想将纹理设置得更透明。
我使用 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);
完成这个过程后,我的纹理透明度看起来没有改变。
我知道我可以通过shader代码修改贴图的alpha值,但是是否可以直接编辑贴图像素值并立即显示效果?
感谢您的建议。
您必须使用 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(如果希望它们考虑您的更改)。
我正在尝试修改纹理的像素值。 例如:我想将纹理设置得更透明。 我使用 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);
完成这个过程后,我的纹理透明度看起来没有改变。
我知道我可以通过shader代码修改贴图的alpha值,但是是否可以直接编辑贴图像素值并立即显示效果?
感谢您的建议。
您必须使用 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(如果希望它们考虑您的更改)。