如何在OpenGL ES 2.0中将浮点数组传递给着色器?

3
我正在尝试在Android的OpenGL ES 2.0中从一个对象类传递一组点光源到顶点着色器中。这些点光源被存储为一个float[]数组,理想情况下,着色器应该将这些浮点数读取为vec4[]数组。
可以通过调用glUniform4fv(...floatArray, 0)将float[]传递到顶点着色器,并在顶点着色器中声明为uniform vec4 u_PointLights[990],但这样做非常慢。
我正在尝试将这些浮点数放入GPU内存中;首先考虑使用VBO,但是绑定数据并将其传递给着色器后,只能读取单个vec4而不能读取数组(即不能声明attribute vec4[] a_PointLights)。
如何最好地将第二个vec4[]传递到着色器中?

1
它的哪个部分非常慢,是传输到着色器统一变量还是实际渲染?如果着色器中有大型复杂的循环和条件语句(分支在着色器中速度较慢),可能会导致一些减速。如果情况不行,使用统一缓冲对象可能更适合传输大型数组,但我认为将数组发送到统一变量应该不会太慢。 - undefined
很遗憾,我不认为在ES 2上有统一缓冲区对象可用,但它们在ES 3中引入了。但是对于着色器本身的查询,我同意:你是如何处理数据的?最好避免在着色器中使用条件和随机访问;像传统命令式程序一样处理着色器通常不会得到好的结果。 - undefined
另外,你调用 glUniform4fv 的频率是多少?每帧一次吗? - undefined
Tommy - 是的,每帧执行一次。 WearyWanderer - 点光源是动态的(来自粒子发生器),因此顶点着色器会将缓冲区中每个点与每个可见三角形中的顶点之间的距离进行比较。 - undefined
1个回答

1
在OpenGL ES 2.0中,你不能做其他的事情 - 要么是客户端统一变量,要么是属性,但这两者都有一定的限制。
在OpenGL ES 3.0中,你可以使用Uniform Buffer Object,但请注意,非常大的统一变量数组总是相对昂贵的,特别是在移动设备上。

感谢Isogen。如果2.0版本中没有本地缓冲区可用,通过纹理映射传递数值与使用float[] uniform并通过glUniform4fv()函数传递数值相比,性能如何? - undefined
并不是所有的OpenGL ES 2.0的GPU都支持顶点着色器纹理——规范中并没有要求,但在ES 3.0中则是强制要求的。性能方面,如果可用的话应该还可以,但你需要将数据打包成颜色格式并重新组装值(再次说明,ES 3.0会有原生的浮点纹理,但ES 2.0没有)。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接