Я пытаюсь найти решение, которое позволит мне вращать точечные спрайты вокруг оси z с изменяющимся атрибутом (т.е. равномерность не подходит).
В моем приложении у меня есть много сотен / тысяч точечных спрайтов, отрисовываемых за кадр, которые затем сохраняются в VBO (вполне возможно, что их количество может оказаться> 1000000). Таким образом, я ищу лучший компромисс между использованием памяти и производительностью.
Текущие вершинные и фрагментные шейдеры выглядят так:
// 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);
- Advantages:
- Keeps shaders simple.
- Простой код для вычисления матриц вне шейдеров (например, с использованием
GLKit
).
- Disadvantages:
- Massively increases the size of my point sprite data (from 16 to 80 bytes/point for a 4x4 matrix; to 52 bytes/point for a 3x3 matrix... I believe it's possible to use a 3x3 rotation matrix?). This could potentially cause my app to crash 3-5 times sooner!
- Выдвигает гораздо больше вычислений на ЦП (сотни / тысячи матричных вычислений на кадр).
- Advantages:
Добавьте атрибут
float angle
к моим данным точечного спрайта, затем вычислите матрицу вращения в вершинном шейдере. Передайте матрицу поворота фрагментному шейдеру, как указано выше.- Advantages:
- Keeps point sprite data size small (from 16 to 20 bytes/point).
- Передает тяжелую матричную математику на GPU.
- Keeps point sprite data size small (from 16 to 20 bytes/point).
- Disadvantages:
- Need to write custom GLSL function to create rotation matrix. Not a massive problem, but my matrix maths is rusty, so this could be error prone, especially if I'm trying to figure out the 3x3 matrix solution...
- Учитывая, что это должно происходить на сотнях / тысячах вершин, будет ли это серьезным тормозом для производительности (несмотря на то, что это обрабатывается графическим процессором)?
- Advantages:
- Я реально мог справиться с 1 байтом для атрибута угла (255 разных углов было бы достаточно). Есть ли способ использовать какой-то поиск, чтобы мне не нужно было без нужды пересчитывать одни и те же матрицы вращения? Моей первой мыслью было сохранение констант в вершинном шейдере, но я не хочу начинать добавлять операторы ветвления в свои шейдеры.
Есть мысли по поводу хорошего подхода?