What command in webgl cause texture memory to be processed
设置单个纹理WebGL程序时,什么命令实际上导致完成"工作"?
在我看来,textImage2D命令将html图像数据上传到GPU:
1 | gl.texImage2D(target, level, internalformat, format, type, HTMLImageElement); |
但是,一旦数据上传并绑定到纹理,该纹理仍需要"绑定"到采样器。
1 2 3 | setActiveTexture(gl, 0, this['textureRef0']); var samplerRef = gl.getUniformLocation(program, 'sampler0'); gl.uniform1i(samplerRef, 0); |
是否需要分配任何内存以将纹理绑定到采样器?还是只是将指针指向纹理数据而更改的指针?
将纹理绑定到帧缓冲区又如何呢?
1 2 | gl.bindFramebuffer(gl.FRAMEBUFFER, this.globalFB); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureRef0, 0); |
单独行动是否会导致任何重大的性能问题?还是仅在调用程序并将数据渲染到该纹理时才完成"真正的"工作?
framebuffers不会分配太多内存,内存是附件。但是,帧缓冲区需要进行验证,因此最好使用所需附件的每种组合制作多个帧缓冲区,而不是更改单个帧缓冲区上的附件
换句话说,例如,如果您正在对纹理进行ping ponging处理后处理,例如
1 2 3 4 5 6 7 8 9 10 | // 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 } |
vs
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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第一次进行纹理绘制时(以及任何时候更改其内容)都有大量工作要做。
考虑到这是WebGL中提供mips的正常顺序
1 2 3 4 5 | texImage2D level 0, 16x16 texImage2D level 1, 8x8 texImage2D level 2, 4x4 texImage2D level 3, 2x2 texImage2D level 4, 1x1 |
但这也是完全有效的API调用
1 2 3 4 5 6 | 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的调用具有某种奇怪的大小是有效的。不允许输入错误。当然,如果您在绘制之前不替换第2级,它将无法绘制,但根据API上传数据并没有错。这意味着直到实际使用纹理时,驱动程序才可以查看每个mip的数据,格式和大小,检查它们是否都正确,然后最终将数据排列在GPU上。
添加了
调用