简体   繁体   English

如何获取 Webgl 纹理的副本

[英]How do I Get Copy of Webgl Texture

I have a webgl texture and I store this texture in a javascript variable我有一个 webgl 纹理,我将此纹理存储在 javascript 变量中

var texture1 = CreateTexture()

function CreateTexture(){
  var texture = gl.createTexture()
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false)
  gl.bindTexture(gl.TEXTURE_2D, texture)
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,canvas)
  gl.generateMipmap(gl.TEXTURE_2D)
  gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
  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.texParameterf(gl.TEXTURE_2D, this.extAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, 2)
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true)
  return texture
}

I want to keep a copy of this texture (texture1) in another variable, not instance.我想将此纹理(texture1)的副本保留在另一个变量中,而不是实例中。 For example for javascript arrays, thanks to the slice function, we can keep a copy of arrays in a variable.例如对于 javascript arrays,感谢切片 function,我们可以在变量中保留 ZA3CBC3F9D0CE2F2C19CDZ4 的副本。

var arr1 = [1,2,3,4,5]
var arr2 = arr1.slice()

How do I do this for webgl textures?我如何为 webgl 纹理执行此操作?

There is no easy way, nor is it guaranteed you can copy a texture.没有简单的方法,也不能保证您可以复制纹理。

To copy texture you need to render to a texture .要复制纹理,您需要渲染到纹理 So you setup a shader and attributes and uniforms to draw the source texture, attach the destination texture to a framebuffer, bind the framebuffer, draw.所以你设置一个着色器和属性和制服来绘制源纹理,将目标纹理附加到帧缓冲区,绑定帧缓冲区,绘制。

You can also use copyTexImage2D.您也可以使用 copyTexImage2D。 It copies from the current framebuffer or canvas if no framebuffer is bound so in that case you take your source texture, attach it to a framebuffer, bind the framebuffer, bind your destination texture, call copyTexImage2D .如果没有绑定帧缓冲区,它会从当前帧缓冲区或 canvas 复制,因此在这种情况下,您获取源纹理,将其附加到帧缓冲区,绑定帧缓冲区,绑定目标纹理,调用copyTexImage2D

Limitation for both methods are两种方法的限制是

  1. not every format of texture can be used as an attachment to a framebuffer.并非每种格式的纹理都可以用作帧缓冲区的附件。 For example in WebGL1 only a texture of format/type RGBA/UNSIGNED_BYTE is guaranteed to be able to be attached to a framebuffer例如,在 WebGL1 中,只有格式/类型 RGBA/UNSIGNED_BYTE 的纹理保证能够附加到帧缓冲区

  2. You can not query the size of a texture in WebGL1 so you'll need to have saved that somewhere on your own您无法在 WebGL1 中查询纹理的大小,因此您需要自己将其保存在某个地方

  3. You can not query the internal format nor format or type of a texture so you'd have to save that.您无法查询纹理的内部格式或格式或类型,因此您必须保存它。 Note that in WebGL2 it's legal for every mip to have a size unrelated to any other mip as well as different internal formats as long as the base and max LODs for the texture are set such that the range of mips used is valid.请注意,在 WebGL2 中,每个 mip 具有与任何其他 mip 无关的大小以及不同的内部格式是合法的,只要设置纹理的基本 LOD 和最大 LOD 以使使用的 mip 范围有效。 That means for a generic copy you'd need to save the dimensions of and internal format of every mip level.这意味着对于通用副本,您需要保存每个 mip 级别的尺寸和内部格式。

  4. You can not query how many mips there are so you'll need to save that info if you care您无法查询有多少 mips,因此如果您关心,您需要保存该信息

  5. You can not easily copy the mips even if you knew how many there are即使知道有多少 mips,也不能轻易复制

    For 1 you can not bind a mip except level 0 to a framebuffer.对于 1,您不能将除级别 0 之外的 mip 绑定到帧缓冲区。 This means the first method won't work for copying mips since you can't specify a mip as the destination for the copy.这意味着第一种方法不适用于复制 mip,因为您无法将 mip 指定为复制的目标。 For the second method you can't specify a mip as the source for the copy so you'd need to write a shader that renders that mip either to the canvas or a another texture and then calls copyTexImage2D to get it into the mip.对于第二种方法,您不能将 mip 指定为副本的源,因此您需要编写一个着色器,将该 mip 渲染到 canvas 或另一个纹理,然后调用 copyTexImage2D 将其放入 mip。

    If you don't care about the contents of the mips you can just copy the level 0 and call generateMipmap如果您不关心 mips 的内容,您可以复制级别 0 并调用generateMipmap

  6. You can not copy a texture if it's not in a renderable state.如果纹理不在可渲染 state 中,则无法复制纹理。

    For example a in WebGL1 with a non-power of 2 texture and filtering set to use mips or repeat.例如,在 WebGL1 中,具有非 2 次幂的纹理和过滤设置为使用 mips 或重复。 Or if the mips are the incorrect sizes or different formats.或者如果 mips 的大小不正确或格式不同。

For the parameters like TEXTURE_MIN_FILTER and TEXTURE_WRAP_S you can call gl.getTextureParameter to query them from one texture and apply them to another, or you can save them yourself like issues 2, and 3 above对于像TEXTURE_MIN_FILTERTEXTURE_WRAP_S这样的参数,您可以调用gl.getTextureParameter从一个纹理中查询它们并将它们应用到另一个纹理,或者您可以像上面的问题 2 和 3 一样自己保存它们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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