小程序下WebGL截图
最近做了关于小程序下WebGL截图的项目,遇到一些坑,记录下。
- 安卓切换页面后返回,再一次获取像素为空
- IOS偶尔获取到的为空白图像
- 获取到的数据绘制出来后上下颠倒
翻THREE.JS的代码,发现正确的截图方法
https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L1903
if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
}
} else {
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
}
所以解决方法
// 在渲染循环里检测checkFramebufferStatus状态,完成后再读取像素
const render = () => {
if (this.disposing) return
requestAnimationFrame(render);
demo.update()
renderer.render(scene, camera);
if (this.screenshotResolve) {
// @ts-ignore 参考 Threejs WebGLRenderer.readRenderTargetPixels
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE) {
// @ts-ignore
gl.readPixels(0, 0, frameBuffer.x, frameBuffer.y, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);
// 翻转Y轴
flip(pixelData, frameBuffer.x, frameBuffer.y, 4);
// 确保有像素,微信小程序安卓在进入子页面返回本页面后,再一次readPixels稳定无像素
if (pixelData.some(i => i !== 0)) {
this.screenshotResolve([pixelData, frameBuffer.x, frameBuffer.y])
this.screenshotResolve = null as unknown as Function;
}
}
}
}
1 回复