首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >支持WebGL1 + WebGL2

支持WebGL1 + WebGL2
EN

Stack Overflow用户
提问于 2019-12-26 23:22:28
回答 2查看 564关注 0票数 1

我有一个库,它使用WebGL1来渲染东西。它大量使用浮点纹理和实例化渲染。

如今,对WebGL1的支持似乎很奇怪,一些设备支持例如WebGL2,其中这些扩展是核心,但不支持WebGL1,或者支持它,但不支持扩展。

与此同时,对WebGL2的支持并不令人惊讶。也许有一天它会是,但对于不是。

我开始研究如何支持这两个版本。

对于着色器,我认为我基本上可以摆脱#define的事情。例如,#define texture2D texture和其他类似的东西。

当涉及到扩展时,它变得更有问题,因为扩展对象不再存在。作为实验,我尝试将扩展属性复制到context对象中,例如gl.drawArraysInstanced = (...args) => ext.drawArraysInstancedANGLE(...args)

当涉及到纹理时,不需要太多的改变,也许在WebGL1中运行时添加类似gl.RGBA8 = gl.RGBA的东西,因此当在WebGL2中运行时它就会“正常工作”。

那么question...did来了,有没有人试过这个?我担心它会影响性能,特别是函数调用的额外间接性。如果假设代码可以在WebGL1中运行,这也会使阅读代码变得不那么明显。毕竟,没有任何WebGL1上下文具有drawArraysInstancedRGBA8。这也会困扰打字和其他次要的事情。

另一种选择是让分支遍及整个代码。两个版本的着色器(或#ifdef技巧),每个需要纹理格式的地方和每个完成实例化的地方都有大量的刷子。像下面这样的东西到处都是,这是相当丑陋的:

代码语言:javascript
运行
复制
if (version === 1) {
  instancedArrays.vertexAttribDivisorANGLE(m0, 1);
  instancedArrays.vertexAttribDivisorANGLE(m1, 1);
  instancedArrays.vertexAttribDivisorANGLE(m2, 1);
  instancedArrays.vertexAttribDivisorANGLE(m3, 1);
} else {
  gl.vertexAttribDivisor(m0, 1);
  gl.vertexAttribDivisor(m1, 1);
  gl.vertexAttribDivisor(m2, 1);
  gl.vertexAttribDivisor(m3, 1);
}

最后,也许还有第三种我没有想到的方法。

有什么建议吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-27 01:04:49

不幸的是,我认为大多数答案将主要基于观点。

第一个问题是为什么两者都支持?如果你的想法在WebGL1上运行良好,那么就使用WebGL1。如果你一定要有WebGL2特性,那就使用WebGL2,并意识到许多设备都不支持WebGL2。

如果你打算这么做,twgl会试着通过providing a function that copies all the WebGL1 extensions into their WebGL2 API positions让它变得更容易。因为就像你提到的,而不是

代码语言:javascript
运行
复制
ext = gl.getExtension('ANGLE_instanced_arrays');
ext.drawArraysInstancedANGLE(...)

相反,你可以这样做

代码语言:javascript
运行
复制
twgl.addExtensionsToContext(gl);
gl.drawArraysInstanced(...);

我不相信会有任何明显的性能差异。特别是因为这些函数在一帧中只被调用几百次,包装不会成为代码中的瓶颈。

不过,重点并不是要同时支持WebGL1和WebGL2。更确切地说,这只是为了使两个API的代码编写方式相同。

尽管如此,这两个API仍然存在真正的差异。例如,要在WebGL1中使用浮动RGBA纹理,可以使用

代码语言:javascript
运行
复制
gl.texImage2D(target, level, gl.RGBA, width, height, 0, gl.RGBA, gl.FLOAT, ...)

在WebGL2中,它是

代码语言:javascript
运行
复制
gl.texImage2D(target, level, gl.RGBA32F, width, height, 0, gl.RGBA, gl.FLOAT, ...)

如果您尝试使用与本例中的WebGL1相同的名称来调用WebGL2,则它将失败。There are other differences也是如此。

在WebGL1和WebGL2中可以很好地工作。该规范特别指出,这种组合导致了WebGL2上的RGBA8。

但请注意,您需要RGBA8的示例并不正确。

代码语言:javascript
运行
复制
gl.texImage2D(target, level, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, ...)

不过,最大的不同之处在于,如果您可以使用WebGL1,就没有理由使用WebGL2。或者,反之亦然,如果你需要WebGL2,那么你可能不能很容易地退回到WebGL1

例如,您提到使用着色器的定义,但是您将如何处理WebGL1中不存在的WebGL2中的功能。诸如textureFetch或mod %运算符或整数属性等功能...如果您需要这些功能,您最需要编写一个仅WebGL2着色器。如果你不需要这些特性,那么从一开始就没有必要使用WebGL2。

当然,如果你真的想要这样做,如果用户有WebGL2,你可能会想做一个更花哨的渲染器,如果是WebGL1,你可能会退回到一个更简单的渲染器。

TD;LR可以选择其中之一

票数 3
EN

Stack Overflow用户

发布于 2021-01-28 02:54:29

我在写我的库的文档时发现了这个问题,这个库有很多目标,但其中一个目标就是-同时支持WebGL1和WebGL2,以获得更高的跨设备兼容性。

https://xemantic.github.io/shader-web-background/

例如,我用BrowserStack发现三星手机不支持在WebGL1中渲染浮点纹理,而在WebGL2中完全可以。同时,WebGL2永远不会出现在苹果设备上,但渲染到半浮点纹理是相当好的支持。

我的库没有提供完整的WebGL抽象,但会为片段着色器配置管道。以下是GitHub上的源代码,其中包含WebGL策略代码,具体取决于版本:

https://github.com/xemantic/shader-web-background/blob/main/src/main/js/webgl-utils.js

因此,要回答你的问题,这是可行的,也是可取的,但对于每个WebGL功能,以一种完全通用的方式来做这件事可能是相当有挑战性的。我想要问的第一个问题是“共同点是什么?”在支持的扩展方面。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59490319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档