antvis / g-webgl-compute

A GPGPU implementation based on WebGL.
MIT License
143 stars 15 forks source link

WebGL 提供判断是否支持 OES_texture_float 的方法 #26

Open xiaoiver opened 4 years ago

xiaoiver commented 4 years ago

问题背景

我们在 WebGL 的实现中使用了 OES_texture_float 扩展进行浮点数纹理的读写。 https://www.khronos.org/registry/webgl/extensions/OES_texture_float/

但是该扩展存在一定兼容性问题,尤其是在移动端 和 Safari 中: http://webglstats.com/webgl/extension/OES_texture_float

经测试:

因此我们需要提供判断方法,或者采用其他兼容方案。

解决方案

提供一个 isFloatSupported 方法,开发者调用后可以自行决定,例如切换到 CPU 算法: https://github.com/regl-project/regl/issues/487 https://github.com/regl-project/regl/commit/6afda7ca1b663835dcec0b11bce2c7e2eeab60a1

另外也可以尝试兼容方案: https://github.com/mikolalysenko/glsl-read-float 在 Shader 中通过 pack 把一个浮点数压缩成 ivec4 渲染到纹理,从纹理中读取数据时进行 unpack

xiaoiver commented 4 years ago

这个判断应该和具体渲染引擎有关,而且由于 WebGL 具体实现中需要尝试读取浮点纹理,通过是否报错判断,因此需要在引擎初始化完成后。最终决定加在 onInit 回调内:

const world = new World(canvas, {
  engineOptions: {
    supportCompute: true,
  },
  onInit: (engine) => {
    console.log(engine.isFloatSupported());
  },
});
xiaoiver commented 4 years ago

tfjs 遇到不支持的浏览器例如低版本的 Safari:

  1. 抛出 WebGL: INVALID_ENUM: readPixels: invalid type
  2. 自动切换成 CPU 版本:

https://github.com/tensorflow/tfjs/issues/287#issuecomment-388382636