【问题标题】:How to pass float array to Shader in OpenGL ES 2.0?如何在 OpenGL ES 2.0 中将浮点数组传递给着色器?
【发布时间】:2016-04-14 11:33:20
【问题描述】:

我正在尝试将一组点光源从对象类传递到 Android 上 OpenGL ES 2.0 中的顶点着色器。

点光源存储为float[] 数组,着色器理想情况下会将浮点数读取为vec4[] 数组。

float[] 可以通过调用glUniform4fv(...floatArray, 0) 传递给顶点着色器,并在顶点着色器中声明为uniform vec4 u_PointLights[990],但这非常慢。

我正在尝试将浮点数放入 GPU 内存中;首先想到的是 VBO,但在绑定数据并将其传递给着色器后,我只能读取单个 vec4 而不是数组(即无法声明 attribute vec4[] a_PointLights)。

让第二个vec4[] 进入着色器的最佳方法是什么?

【问题讨论】:

  • 它的哪一部分非常慢,转移到着色器统一或只是实际渲染?如果存在大型复杂的 for 循环和 if 语句(着色器中的分支很慢),您的着色器可能会有些减速将您的数组发送到制服。
  • 我不认为统一缓冲区对象在 ES 2 上可用,遗憾的是,尽管它们随 ES 3 一起出现。但其次是关于着色器本身的查询:你如何处理数据?在着色器中最好避免条件性和随机访问;像传统的命令式程序一样攻击一个通常不会产生好的结果。
  • 另外,您多久致电一次glUniform4fv?每帧一次?
  • Tommy - 是的,每帧一次。 WearyWanderer - 点光源是动态的(来自粒子生成器),因此顶点着色器将缓冲区中每个点与每个可见三角形中每个顶点的距离进行比较。

标签: android arrays opengl-es


【解决方案1】:

在 OpenGL ES 2.0 中,您实际上不能做任何其他事情 - 无论是客户端统一还是属性,这两者都会受到一定的限制。

在 OpenGL ES 3.0 中,您可以使用统一缓冲区对象,但请注意,非常大的统一数组总是相对昂贵,尤其是在移动设备上。

【讨论】:

  • 感谢 Isogen。如果原生缓冲区在 2.0 中不可用,那么通过纹理贴图传递值的性能与通过 glUniform4fv 使用 float[] 制服相比如何?
  • 并非所有 OpenGL ES 2.0 GPU 都支持顶点着色器纹理——规范中没有要求——尽管在 ES 3.0 中是强制性的。性能方面,如果可用的话应该没问题,但是您必须将数据打包成颜色格式并重新组合值(同样,ES 3.0 将具有本机 loat 纹理,但 ES 2.0 没有)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多