glsl - WebGL/GLSL 中间变量是否可以提高性能且没有任何缺点?

标签 glsl webgl

当使用至少 2 次以上时,中间变量是否可以系统地提高性能且没有任何缺点?

让我们举一个实用的例子:

vec4 right = doubleUV + vec4(size.x, 0.0, 2.0 * size.x, 0.0);
vec4 left  = doubleUV - vec4(size.x, 0.0, 2.0 * size.x, 0.0);
vec4 up    = doubleUV + vec4(0.0, size.y, 0.0, 2.0 * size.y);
vec4 down  = doubleUV - vec4(0.0, size.y, 0.0, 2.0 * size.y);  

我们可以看到 2.0 * size.x2.0 * size.y 并使用了多次。使用中间变量让我直观地将这段代码重构为:

float sizex2 = 2.0 * size.x;
vec4 right = doubleUV + vec4(size.x, 0.0, sizex2, 0.0);
vec4 left  = doubleUV - vec4(size.x, 0.0, sizex2, 0.0);

float sizey2 = 2.0 * size.y;
vec4 up    = doubleUV + vec4(0.0, size.y, 0.0, sizey2);
vec4 down  = doubleUV - vec4(0.0, size.y, 0.0, sizey2);  

除了可读性之外,这是一个可以系统应用的良好的“无需思考”的性能实践吗?或者我应该考虑额外乘法与变量分配的性能成本?

作为一个附带问题:额外的临时变量可能会损害性能吗?这很难测试,因为 GLSL 代码是针对 WebGL 的,并且将由多种编译器编译。某些 GLSL 编译器是否足够智能,可以将冗余的小代码片段分组?

最佳答案

对于简单的重复乘法,临时变量不会提高性能。但是,当进行更复杂的运算(如倒数、平方、平方根、点积)时,引入额外的变量可能会产生明显的影响(对于不会优化它的编译器)。

我不会担心插入临时变量的性能,因为这些变量将存储到 GPU 矢量化寄存器中。
但是,如果您添加的变量多于寄存器,您将面临以下风险:

  • 在某些 GPU 上编译着色器失败。
  • 寄存器溢出,其中需要直接从 GPU 执行单元本地内存 ( ARM mobile GPU docs ) 存储和访问变量。

作为替代方法(至少对我来说更清楚):

vec4 v1 = vec4(size.x, 0.0, 2.0 * size.x, 0.0);
vec4 right = doubleUV + v1;
vec4 left  = doubleUV - v1;

vec4 v2 = vec4(0.0, size.y, 0.0, 2.0 * size.y);
vec4 up    = doubleUV + v2;
vec4 down  = doubleUV - v2; 

Here您可以看到 GGX 着色模型以及分组为变量的操作的复杂性。

关于glsl - WebGL/GLSL 中间变量是否可以提高性能且没有任何缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76412220/

相关文章:

opengl - 如何确保屏幕空间导数存在于三角形边缘?

ios - 解决奇怪的行为 re : glsl/metal shader.(无意的坐标翻转)

javascript - Babylon.js 重复纹理接缝/工件

css - Famo.us css 3d 转换

javascript - Three.js WebGL 渲染器不更新面部的 Color 属性

opengl - 为什么要通过模型 View 矩阵的逆矩阵转置来变换法线?

java - GLSL 中没有出现纹理的可能原因有哪些?

opengl - 如何在OpenGL中归一化纹理空间的图像坐标?

javascript - 在 Three.js 中访问立方体一个面上的所有顶点

javascript - 在 ThreeJs 中围绕中心点上下移动 3D 相机