webgl 中的什么命令导致纹理内存被处理 [英] What command in webgl cause texture memory to be processed

查看:49
本文介绍了webgl 中的什么命令导致纹理内存被处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在设置单个纹理 WebGL 程序时,什么命令实际上会导致工作"完成?

When setting up a single texture WebGL program what command actually causes "work" to be done?

在我看来,textImage2D 命令将 html 图像数据上传到 GPU:

It seems to me that the textImage2D command upload html image data to the GPU:

gl.texImage2D(target, level, internalformat, format, type, HTMLImageElement);

然而,一旦数据上传并绑定到纹理,该纹理仍然需要绑定"到采样器.

However once that data is uploaded and bound to a texture, that texture still needs to be "bound" to a sampler.

setActiveTexture(gl, 0, this['textureRef0']);
var samplerRef = gl.getUniformLocation(program, 'sampler0');
gl.uniform1i(samplerRef, 0);

是否需要分配任何内存来将纹理绑定到采样器?或者它只是一个改变采样器指向纹理数据的指针?

Does any memory need to be allocated to bind the texture to the sampler? Or is it just a pointer that changes which points the sampler to the texture data?

还有如何将纹理绑定到帧缓冲区?

Also what about binding textures to frame buffers?

gl.bindFramebuffer(gl.FRAMEBUFFER, this.globalFB);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureRef0, 0);

单独行动会导致任何重大的性能问题吗?还是只有在调用程序并将数据渲染到该纹理中时才完成真正的"工作?

Does that act alone cause any significant performance issues? Or is "real" work only done when the program is called and data is rendered into that texture?

推荐答案

texImage2D 分配内存,因为驱动程序需要制作一份你传递给它的数据的副本 texImage2D代码>返回你可以改变你的记忆.

texImage2D allocates memory because the driver needs to make a copy of the data you pass it as the moment texImage2D returns you can change your memory.

帧缓冲区不分配太多内存,内存是附件.但是,需要验证帧缓冲区,因此最好使用您需要的每种附件组合制作多个帧缓冲区,而不是更改单个帧缓冲区上的附件

framebuffers don't allocate much memory, the memory is the attachments. But, framebuffers need to be validated so it's better to make multiple framebuffers with every combination of attachments you need rather than change the attachments on a single framebuffer

换句话说,例如,如果您正在对纹理进行乒乓处理以进行后期处理

In other words, for example if you're doing ping ponging of textures for post processing for example

 // init time
 const fb = gl.createFramebuffer();

 // render time
 for each pass
    gl.framebufferTexture2D(...., dstTex);   // bad!
    ...
    gl.drawXXX
    const t = srcTex; srcTex = dstTex; dstTex = t;  // swap textures
 }

对比

 // init time
 let srcFB = gl.createFramebuffer();
 gl.framebufferTexture(...., srcTex);
 let dstFB = gl.createFramebuffer();
 gl.framebufferTexture(...., dstTex);

 // render time
 for each pass
    gl.bindFramebuffer(dstFB);   // good
    ...
    gl.drawXXX
    const t = srcFB; srcFB = dstFB; dstFB = t;  // swap framebuffers
 }

纹理也有一个问题,因为 API 设计,GL 在你第一次用纹理绘制时(以及任何时候你改变它的内容)有很多工作要做.

textures also have the issue that because of the API design GL has a bunch of work to do the first time you draw with a texture (and any time you change it's contents).

认为这是 WebGL 中提供 mips 的正常序列

Consider this is a normal sequence in WebGL to supply mips

texImage2D level 0, 16x16
texImage2D level 1, 8x8
texImage2D level 2, 4x4
texImage2D level 3, 2x2
texImage2D level 4, 1x1

但这也是完全有效的 API 调用

But this is also completely valid API calls

texImage2D level 0, 16x16
texImage2D level 1, 8x8
texImage2D level 2, 137x324    // nothing in the spec prevents this. It's fully valid
texImage2D level 3, 2x2
texImage2D level 4, 1x1
texImage2D level 2, 4x4        // fix level 2 before drawing

以某种奇怪的大小调用第 2 级是有效的.不允许出现错误.当然,如果你在绘制之前不替换level 2,它会绘制失败,但根据API上传数据并没有错.这意味着直到实际使用纹理时,驱动程序才能查看每个 mip 的数据、格式和大小,检查它们是否都正确,然后最终将数据排列在 GPU 上.

That call to level 2 with some strange size is valid. It's not allowed to give an error. Of course if you don't replace level 2 before drawing it will fail to draw but uploading the data is not wrong according to the API. That means it isn't until the texture is actually used that the driver can look at the data, formats, and sizes for each mip, check if they are all correct, and then finally arrange the data on the GPU.

texStorage 以解决该问题(在 WebGL2/OpenGL ES 3.0 中可用)

texStorage was added to fix that issue (available in WebGL2/OpenGL ES 3.0)

调用activeTexture,使用bindTexture绑定纹理,设置uniform不占用内存,也没有明显的性能问题.

Calling activeTexture, binding textures with bindTexture, and setting uniforms take no memory and have no significant performance issues.

这篇关于webgl 中的什么命令导致纹理内存被处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆