【发布时间】:2012-10-10 09:20:57
【问题描述】:
我正在尝试找到一种解决方案,该解决方案允许我使用不同的属性围绕 z 轴旋转点精灵(即,uniform 不会这样做)。
在我的应用程序中,我每帧绘制了成百上千个点精灵,然后将它们存储在 VBO 中(很可能最终会超过 1,000,000)。因此,我正在寻找内存使用和性能之间的最佳折衷方案。
当前的顶点和片段着色器如下所示:
// VERTEX SHADER
attribute vec4 a_position;
attribute vec4 a_color;
attribute float a_size;
uniform mat4 u_mvpMatrix;
varying vec4 v_color;
void main()
{
v_color = a_color;
gl_Position = u_mvpMatrix * a_position;
gl_PointSize = a_size;
}
// FRAGMENT SHADER
precision mediump float;
uniform sampler2D s_texture;
varying vec4 v_color;
void main()
{
vec4 textureColor = texture2D(s_texture, gl_PointCoord);
gl_FragColor = v_color * textureColor;
}
我目前可以想象以下几种可能性:
-
为我的点精灵数据添加一个
mat4 rotMatrix属性。将此传递给片段着色器并旋转每个片段:vec2 texCoord = (rotMatrix * vec4(gl_PointCoord, 0, 1)).xy gl_FragColor = v_color * texture2D(s_texture, texCoord);- 优点:
- 保持着色器简单。
- 在着色器之外计算矩阵的简单代码(例如使用
GLKit)。
- 缺点:
- 大幅增加了我的点精灵数据的大小(对于 4x4 矩阵从 16 字节/点增加到 80 字节/点;对于 3x3 矩阵从 52 字节/点...我相信可以使用 3x3 旋转矩阵?)。这可能会导致我的应用提前 3-5 次崩溃!
- 将更多计算推送到 CPU 上(每帧数十/千次矩阵计算)。
- 优点:
-
在我的点精灵数据中添加
float angle属性,然后在顶点着色器中计算旋转矩阵。如上所述将旋转矩阵传递给片段着色器。- 优点:
- 使点精灵数据大小保持较小(从 16 到 20 字节/点)。
- 将繁重的矩阵数学推送到 GPU。
- 使点精灵数据大小保持较小(从 16 到 20 字节/点)。
- 缺点:
- 需要编写自定义 GLSL 函数来创建旋转矩阵。不是一个大问题,但我的矩阵数学很生疏,所以这可能很容易出错,尤其是当我试图找出 3x3 矩阵解决方案时......
- 鉴于这必须发生在成百上千个顶点上,这是否会严重拖累性能(尽管由 GPU 处理)?
- 优点:
- 我可以实际处理 1 个字节的角度属性(255 个不同的角度就足够了)。有什么办法可以使用某种查找,这样我就不需要不必要地重新计算相同的旋转矩阵?在顶点着色器中存储常量是我的第一个想法,但我不想开始在我的着色器中放置分支语句。
有什么好的方法吗?
【问题讨论】:
标签: ios matrix opengl-es-2.0 shader point-sprites