小程序下WebGL截图
发布于 4 年前 作者 xiulanguo 1709 次浏览 来自 分享

最近做了关于小程序下WebGL截图的项目,遇到一些坑,记录下。

  1. 安卓切换页面后返回,再一次获取像素为空
  2. IOS偶尔获取到的为空白图像
  3. 获取到的数据绘制出来后上下颠倒

翻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;
      }
    }
  }
}

具体可阅读代码片段 https://developers.weixin.qq.com/s/syS4xzmw7AnO

1 回复

小程序下可用的three 可更新、降级three、使用自定义three

https://github.com/deepkolos/three-platformize

回到顶部