最好在javascript或着色器中乘以矩阵?

sta*_*wed 6 javascript performance webgl

我一直在看几个webgl示例.考虑MDN的教程.它们的顶点着色器将顶点乘以透视矩阵和世界位置矩阵:

gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);

uMVMatrix它本身是在一些矩阵库的帮助下在javascript中计算的几种变换(平移,旋转等)的产物.

似乎直接在着色器中计算他们的产品会更快; 肯定比在.js中做得更快.他们选择这种方法有什么理由吗?

现在,我猜你可以用这种方式以任意顺序堆叠任意数量的变换,这样更灵活.但是说不需要灵活性,有没有理由避免在着色器中直接进行变换?就像是

gl_Position = uPMatrix * uRotationMatrix * uScaleMatrix * uTranslationMatrix * vec4(aVertexPosition, 1.0);

e:要添加一些上下文,在我的特定情况下,我将只渲染2D矩形实体(主要是精灵),因此顶点的数量总是只有4.

鉴于引入库进行快速.js矩阵乘法的开销,似乎将这些计算推入着色器绝对是我的个人情况的方法.

(另外,即使它在平衡中比在javascript中执行速度慢,将计算分流到GPU中也可能是有价值的!)

gma*_*man 8

这取决于 ....

如果在着色器中执行此操作,则会对每个顶点(顶点着色器)或每个像素(片段着色器)执行此操作.即使GPU没有无限速度,所以假设你正在绘制100万个顶点.这可能是JavaScript中的一组矩阵数学计算与GPU上的100万次矩阵计算,JavaScript将获胜.

当然你的milage可能非常.每个GPU都不同.有些GPU比其他GPU快.一些驱动程序在CPU上进行顶点计算.有些CPU比其他CPU快.

您可以测试,不幸的是,因为您正在为Web编写,您不知道用户正在运行什么浏览器,也不知道CPU速度或GPU或驱动程序等等.所以,它真的取决于.

最重要的是,将矩阵传递给着色器也是一种非自由操作.换句话说,调用gl.uniformMatrix4fv一次比你在示例中显示的4倍更快.如果您正在绘制3000个对象,那么12000个调用gl.uniformMatrix4fv(每个4个矩阵)是否明显慢于3000个调用(每个1个矩阵)是您必须测试的内容.

此外,浏览器团队正致力于通过JavaScript更快地制作数学矩阵并尝试使其更接近C/C++.

我想这意味着除了测试之外没有正确的答案,并且每个平台/浏览器/ gpu/drivers/cpu的结果都不同.