gpt4 book ai didi

ios - 具有不同旋转的 OpenGL ES 2.0 点 Sprite - 在着色器中计算矩阵?

转载 作者:行者123 更新时间:2023-12-02 02:25:19 25 4
gpt4 key购买 nike

我正在尝试找到一种解决方案,允许我使用不同的属性绕 z 轴旋转点 Sprite (即,uniform 不行)。

在我的应用程序中,每帧绘制数百/数千个点 Sprite ,然后将其存储在 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;
}

我目前可以想象以下可能性:

  • 向我的点 Sprite 数据添加一个 mat4 rotMatrix 属性。将其传递给片段着色器并旋转每个片段:

    vec2 texCoord = (rotMatrix * vec4(gl_PointCoord, 0, 1)).xy
    gl_FragColor = v_color * texture2D(s_texture, texCoord);
    • 优点:
      • 保持着色器简单。
      • 在着色器外部计算矩阵的简单代码(例如使用 GLKit)。
    • 缺点:
      • 大幅增加点 Sprite 数据的大小(对于 4x4 矩阵,从 16 字节/点增加到 80 字节/点;对于 3x3 矩阵,增加到 52 字节/点……我相信可以使用 3x3 旋转矩阵吗?)。这可能会导致我的应用崩溃时间提前 3-5 倍!
      • 将更多计算推到 CPU 上(每帧数百/数千次矩阵计算)。


  • 向我的点 Sprite 数据添加一个 float 角度属性,然后在顶点着色器中计算旋转矩阵。如上所示将旋转矩阵传递给片段着色器。

    • 优点:
      • 保持点 Sprite 数据较小(从 16 到 20 字节/点)。
      • 将繁重的矩阵数学推至 GPU。
    • 缺点:
      • 需要编写自定义 GLSL 函数来创建旋转矩阵。这不是一个大问题,但我的矩阵数学很生疏,所以这可能很容易出错,特别是当我试图找出 3x3 矩阵解决方案时......
      • 鉴于这必须发生在数百/数千个顶点上,这是否会严重拖累性能(尽管由 GPU 处理)?


  • 我实际上可以处理 1 个字节的角度属性(255 个不同的角度就足够了)。有什么方法可以使用某种查找,这样我就不需要不必要地重新计算相同的旋转矩阵?在顶点着色器中存储常量是我的第一个想法,但我不想开始在我的着色器中放置分支语句。

有什么好的方法吗?

最佳答案

我最终采用的解决方案是问题中的第二个:计算顶点着色器中的旋转矩阵。这样做有以下优点:

  • 保持点 Sprite 数据大小较小。
  • 旋转计算由 GPU 执行。

我猜测的缺点似乎并不适用。即使在第一代 iPad 上运行,我也没有注意到性能受到影响。 GLSL中的矩阵计算有点麻烦,但是效果很好。为了其他尝试做同样事情的人的利益,这里是顶点着色器的相关部分:

//...
attribute float a_angle;
varying mat4 v_rotationMatrix;

void main()
{
//...

float cos = cos(a_angle);
float sin = sin(a_angle);
mat4 transInMat = mat4(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.0);
mat4 rotMat = mat4(cos, -sin, 0.0, 0.0,
sin, cos, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
mat4 resultMat = transInMat * rotMat;
resultMat[3][0] = resultMat[3][0] + resultMat[0][0] * -0.5 + resultMat[1][0] * -0.5;
resultMat[3][1] = resultMat[3][1] + resultMat[0][1] * -0.5 + resultMat[1][1] * -0.5;
resultMat[3][2] = resultMat[3][2] + resultMat[0][2] * -0.5 + resultMat[1][2] * -0.5;
v_rotationMatrix = resultMat;

//...
}

鉴于没有明显的性能影响,该解决方案是理想的,因为不需要创建纹理映射/查找并消耗额外的内存,并且它使其余代码保持干净和简单。

我不能说为每个顶点计算矩阵没有缺点(例如,会缩短电池生命周期),并且在不同场景下性能可能会成为问题,但它适合我的需要。

关于ios - 具有不同旋转的 OpenGL ES 2.0 点 Sprite - 在着色器中计算矩阵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12979696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com