【发布时间】:2021-09-25 01:57:47
【问题描述】:
我有一个使用 WebGL1 来渲染东西的库。 它大量使用浮动纹理和实例化渲染。
现在似乎对 WebGL1 的支持很奇怪,有些设备支持例如 WebGL2,这些扩展是核心,但不支持 WebGL1,或者支持它,但不支持扩展。
同时,对 WebGL2 的支持并不令人惊奇。也许有一天会,但不是。
我开始研究支持这两个版本需要什么。
对于着色器,我想我基本上可以摆脱#defineing 的事情。比如#define texture2D texture等类似的东西。
当涉及到扩展时,问题就更大了,因为扩展对象不再存在。
作为一个实验,我尝试将扩展属性复制到上下文对象中,例如gl.drawArraysInstanced = (...args) => ext.drawArraysInstancedANGLE(...args).
在纹理方面,不需要改变太多,在 WebGL1 中运行时可能添加 gl.RGBA8 = gl.RGBA 之类的东西,因此在 WebGL2 中运行时它会“正常工作”。
那么问题来了……有人试过吗?
我担心它会损害性能,尤其是函数调用的额外间接性。
如果假设它可以在 WebGL1 中运行,它也会使阅读代码变得不那么明显。毕竟,没有 WebGL1 上下文有 drawArraysInstanced 或 RGBA8。这也困扰着 Typescript 打字和其他小事。
另一种选择是在整个代码中都有分支。两个版本的着色器(或#ifdefrickery),每个需要纹理格式的地方和每个完成实例化的地方都有很多分支。
到处都是这样的东西是很丑陋的:
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);
}
最后,也许还有第三种我没有想到的方法。
有什么建议吗?
【问题讨论】:
标签: webgl webgl2 webgl-extensions