如何获取 Webgl 纹理的副本
How do I Get Copy of Webgl Texture
我有一个 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
}
我想在另一个变量而不是实例中保留此纹理 (texture1) 的副本。
例如对于 javascript 数组,多亏了 slice 函数,我们可以在变量中保留数组的副本。
var arr1 = [1,2,3,4,5]
var arr2 = arr1.slice()
如何为 webgl 纹理执行此操作?
没有简单的方法,也不能保证您可以复制纹理。
要复制纹理,您需要 render to a texture。所以你设置了一个着色器和属性和制服来绘制源纹理,将目标纹理附加到帧缓冲区,绑定帧缓冲区,绘制。
你也可以使用copyTexImage2D。如果没有绑定帧缓冲区,它会从当前帧缓冲区或 canvas 复制,因此在这种情况下,您获取源纹理,将其附加到帧缓冲区,绑定帧缓冲区,绑定目标纹理,调用 copyTexImage2D
.
两种方法的限制是
并非每种格式的纹理都可以用作帧缓冲区的附件。例如,在 WebGL1 中,只有 format/type RGBA/UNSIGNED_BYTE 的纹理可以保证能够附加到帧缓冲区
您无法在 WebGL1 中查询纹理的大小,因此您需要自己将其保存在某个地方
您无法查询内部格式,也无法查询纹理的格式或类型,因此您必须保存它。请注意,在 WebGL2 中,每个 mip 具有与任何其他 mip 无关的大小以及不同的内部格式都是合法的,只要设置纹理的基本和最大 LOD,以便使用的 mip 范围有效。这意味着对于通用副本,您需要保存每个 mip 级别的尺寸和内部格式。
您无法查询有多少个 mip,因此如果您需要,则需要保存该信息
即使知道有多少 mip,也无法轻易复制它们
对于 1,您不能将级别 0 以外的 mip 绑定到帧缓冲区。这意味着第一种方法不适用于复制 mip,因为您无法将 mip 指定为复制的目标。对于第二种方法,您不能将 mip 指定为副本的源,因此您需要编写一个着色器,将该 mip 渲染到 canvas 或另一个纹理,然后调用 copyTexImage2D 将其放入mip.
如果您不关心 mip 的内容,您可以只复制级别 0 并调用 generateMipmap
不能复制未处于可渲染状态的纹理。
例如 WebGL1 中的 a 具有非 2 的幂纹理和过滤
设置为使用 mips 或重复。或者如果 mip 的大小不正确或
不同的格式。
对于像TEXTURE_MIN_FILTER
和TEXTURE_WRAP_S
这样的参数,你可以调用gl.getTextureParameter
从一个纹理中查询它们并将它们应用到另一个纹理,或者你可以像问题2一样自己保存它们,和以上 3
我有一个 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
}
我想在另一个变量而不是实例中保留此纹理 (texture1) 的副本。 例如对于 javascript 数组,多亏了 slice 函数,我们可以在变量中保留数组的副本。
var arr1 = [1,2,3,4,5]
var arr2 = arr1.slice()
如何为 webgl 纹理执行此操作?
没有简单的方法,也不能保证您可以复制纹理。
要复制纹理,您需要 render to a texture。所以你设置了一个着色器和属性和制服来绘制源纹理,将目标纹理附加到帧缓冲区,绑定帧缓冲区,绘制。
你也可以使用copyTexImage2D。如果没有绑定帧缓冲区,它会从当前帧缓冲区或 canvas 复制,因此在这种情况下,您获取源纹理,将其附加到帧缓冲区,绑定帧缓冲区,绑定目标纹理,调用 copyTexImage2D
.
两种方法的限制是
并非每种格式的纹理都可以用作帧缓冲区的附件。例如,在 WebGL1 中,只有 format/type RGBA/UNSIGNED_BYTE 的纹理可以保证能够附加到帧缓冲区
您无法在 WebGL1 中查询纹理的大小,因此您需要自己将其保存在某个地方
您无法查询内部格式,也无法查询纹理的格式或类型,因此您必须保存它。请注意,在 WebGL2 中,每个 mip 具有与任何其他 mip 无关的大小以及不同的内部格式都是合法的,只要设置纹理的基本和最大 LOD,以便使用的 mip 范围有效。这意味着对于通用副本,您需要保存每个 mip 级别的尺寸和内部格式。
您无法查询有多少个 mip,因此如果您需要,则需要保存该信息
即使知道有多少 mip,也无法轻易复制它们
对于 1,您不能将级别 0 以外的 mip 绑定到帧缓冲区。这意味着第一种方法不适用于复制 mip,因为您无法将 mip 指定为复制的目标。对于第二种方法,您不能将 mip 指定为副本的源,因此您需要编写一个着色器,将该 mip 渲染到 canvas 或另一个纹理,然后调用 copyTexImage2D 将其放入mip.
如果您不关心 mip 的内容,您可以只复制级别 0 并调用
generateMipmap
不能复制未处于可渲染状态的纹理。
例如 WebGL1 中的 a 具有非 2 的幂纹理和过滤 设置为使用 mips 或重复。或者如果 mip 的大小不正确或 不同的格式。
对于像TEXTURE_MIN_FILTER
和TEXTURE_WRAP_S
这样的参数,你可以调用gl.getTextureParameter
从一个纹理中查询它们并将它们应用到另一个纹理,或者你可以像问题2一样自己保存它们,和以上 3