Sto cercando di trovare una soluzione che mi consenta di ruotare sprite di punti attorno all'asse z con un attributo variabile (ad esempio, l'uniforme non funzionerà).Sprites di punto OpenGL ES 2.0 con rotazioni distinte - calcolare la matrice nello shader?
Nella mia app ho molte centinaia/migliaia di sprite di punti che vengono disegnate per fotogramma, che vengono quindi memorizzate in VBO (può essere quasi fattibile> 1.000.000). In quanto tale, sto cercando il miglior compromesso tra utilizzo della memoria e prestazioni.
Vertex shaders & frammento aspetto attuale come questo:
// 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;
}
posso immaginare attualmente le seguenti possibilità:
Aggiungere un attributo
mat4 rotMatrix
i miei dati punto sprite. Passare questo allo shader frammento e ruotare ogni frammento:vec2 texCoord = (rotMatrix * vec4(gl_PointCoord, 0, 1)).xy gl_FragColor = v_color * texture2D(s_texture, texCoord);
- Vantaggi:
- Mantiene shader semplice.
- Codice semplice per calcolare matrici al di fuori degli shader (utilizzando
GLKit
ad esempio).
- Svantaggi:
- aumenta notevolmente la dimensione dei dati sprite punti (da 16 a 80 byte/punto per una matrice 4x4; a 52 byte/punto per una matrice 3x3 ... Credo che sia possibile usare una matrice di rotazione 3x3?). Ciò potrebbe potenzialmente causare il crash della mia app 3-5 volte prima!
- Spinge molto più il calcolo sulla CPU (centinaia/migliaia di calcoli a matrice per fotogramma).
- Vantaggi:
Aggiungere un attributo
float angle
miei dati punto sprite, quindi calcolare la matrice di rotazione nel vertex. Passa la matrice di rotazione allo shader del frammento come sopra.- Vantaggi:
- mantiene il punto dimensione dei dati sprite piccola (da 16 a 20 byte/punto).
- Spinge la matematica della matrice di sollevamento pesante alla GPU.
- mantiene il punto dimensione dei dati sprite piccola (da 16 a 20 byte/punto).
- Svantaggi:
- bisogno di scrivere la funzione GLSL personalizzato per creare matrice di rotazione. Non è un problema enorme, ma la matematica della mia matrice è arrugginita, quindi potrebbe essere soggetta a errori, soprattutto se sto cercando di capire la soluzione 3x3 matrix ...
- Dato che questo deve accadere su centinaia/migliaia di vertici, questo sarà un serio ostacolo alle prestazioni (nonostante sia gestito dalla GPU)?
- Vantaggi:
- ho potuto realisticamente affrontare 1 byte per l'attributo angolo (255 angolazioni diverse sarebbero sufficienti). C'è un modo in cui posso usare qualche tipo di ricerca in modo da non dover ricalcolare inutilmente le stesse matrici di rotazione? Memorizzare le costanti nel vertex shader è stato il mio primo pensiero, ma non voglio iniziare a inserire dichiarazioni di rami nei miei ombreggiatori.
Qualche idea su un buon approccio?
Ciao, non l'ho ancora provato e sembra una soluzione ragionevole. Da quando ho postato la domanda ho risolto il mio problema, ma ho dimenticato di postare la risposta (grazie per avermelo ricordato!). Ho finito per calcolare la matrice di rotazione nel vertex shader.Il colpo di performance è trascurabile anche su un iPad di 1 gen, e mantiene le mie strutture dati piccole. Il tuo metodo potrebbe anche funzionare, ma uno svantaggio è che aumenterebbe l'utilizzo della memoria delle texture (avrei bisogno di oltre 200 rotazioni per ogni sprite). Mi piace la soluzione vertex shader perché non ho bisogno di giocherellare con gli sprite e le prestazioni sono accettabili. – Stuart