【问题标题】:Plasma Shader Performance in OpenGL ES 2.0OpenGL ES 2.0 中的等离子着色器性能
【发布时间】:2014-01-05 16:34:11
【问题描述】:

我在我的 Android (libGDX) 应用程序中使用了等离子着色器,我从这里找到了它:

http://www.bidouille.org/prog/plasma

这是我的着色器(稍作修改):

#define LOWP lowp
precision mediump float;
#else
define LOWP
#endif
#define PI 3.1415926535897932384626433832795

uniform float time;
uniform float alpha;
uniform vec2 scale;

void main() {
  float v = 0.0;
  vec2 c = gl_FragCoord.xy * scale - scale/2.0;
  v += sin((c.x+time));
  v += sin((c.y+time)/2.0);
  v += sin((c.x+c.y+time)/2.0);
  c += scale/2.0 * vec2(sin(time/3.0), cos(time/2.0));
  v += sin(sqrt(c.x*c.x+c.y*c.y+1.0)+time);
  v = v/2.0;
  vec3 col = vec3(1, sin(PI*v), cos(PI*v));
  gl_FragColor = vec4(col *.5 + .5, alpha);
}

我通过 ImmediateModeRendererGL20 将其渲染为四边形。

但是,对于我的需求来说,它似乎太慢了。我试图用着色器填充我的 Nexus 7(第一代)上的几乎整个屏幕,但我什至无法接近 60 FPS。

这真的是我第一次真正进入 GLSL 世界,我不知道这些东西通常应该如何执行!

我想知道如何优化这个着色器?我真的不在乎图像质量,我可以牺牲它。我得出的结论是,某种查找表可能是我所追求的和/或降低着色器的分辨率..?但我不太确定从哪里开始。我对 GLSL 还很陌生,“低级”编程从来都不是我真正喜欢的,但我渴望至少尝试一下!

【问题讨论】:

  • 不要吹毛求疵,但您列出的着色器在开头缺少至少一行。正如现在显示的那样,您有一个无与伦比的 #if/#else/#endif 预处理器分支。
  • 另外,gl_FragCoord.xy 被插入到屏幕对齐的四边形中...如果您真的不关心图像质量,您实际上可以将四边形拆分为一个一堆瓦片并在顶点着色器中评估它。图像质量和处理时间将随着您决定使用的图块数量而增加。
  • 请同时提供顶点和片段着色器。

标签: android opengl-es opengl-es-2.0 glsl shader


【解决方案1】:

加快速度的最终方法是预先计算大量计算的东西(sin()cos() 的东西)并将其烘焙到纹理中,然后从中获取准备好的值。这将使其超快,因为您的着色器不会进行任何繁重的计算,但会消耗预先计算的值。

正如 cmets 中所述,您可以通过将某些计算移至顶点着色器来优化性能。比如你可以移动这条线

vec2 c = gl_FragCoord.xy * scale - scale/2.0;

在不牺牲任何质量的情况下使用顶点着色器,因为这是一个线性函数,因此插值不会扭曲它。 这样做:

// vertex
...
uniform float scale;
varying mediump vec2 c;
const float TWO = 2.0;
...
void main() {
    ...
    gl_FragCoord = ...
    c = gl_FragCoord.xy * scale - scale / TWO;
    ...
}

// fragment
...
varying mediump vec2 c;
...
void main() {
    ...
    // just use `c` as usual
    ...
}

另外,请使用常量而不是文字 - 文字使用您的统一空间。虽然这可能不会影响性能,但它仍然很糟糕(如果你使用它们太多,你可能会在某些 GPU 上用完最大制服)。更多信息:Declaring constants instead of literals in vertex shader. Standard practice, or needless rigor?

【讨论】:

  • 感谢您的回答!我决定试试查找表,我已经设法得到一个已经显示的静态等离子体。对不起,如果在这里听起来很慢,但我有点难以掌握时间的概念。如果您(或其他任何人)可以通过查找表解释时间变量背后的理论,那就太好了!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多