Quali sono i vantaggi della moltiplicazione della matrice rispetto alle singole variabili (grafica)?

3

Sto imparando OpenGL e le esercitazioni ( 1 , 2 ) Sto leggendo insegnami che per ridimensionare / ruotare / tradurre un oggetto devi conoscere la moltiplicazione della matrice. Perché? Invece di 3x3 matrix puoi usare 6 float: scale_x , scale_y , sin_a , cos_a , mov_x e mov_y . Risulterebbero in ...

  • Meno GPU e utilizzo della CPU (la moltiplicazione della matrice richiede 9 moltiplicazioni e 6 aggiunte mentre le singole variabili richiedono 6 moltiplicazioni e 4 aggiunte. Inoltre, se si desidera spostare l'oggetto, invece di dover moltiplicare l'intera matrice, si modificano solo i valori di due galleggianti.
  • Minore larghezza di banda della memoria (1/3 di taglio!)
  • Più facile da manipolare (almeno in C, nessuna necessità di funzioni di manipolazione della matrice)
  • Estrazione più semplice delle informazioni per ottenere la rotazione dell'oggetto o l'offset o la scala

Gli unici svantaggi che conosco sono:

  • Non è possibile modificare l'ordine delle trasformazioni, soprattutto la rotazione attorno ad un punto, non l'origine della coordinata. Puoi comunque simularlo modificando mov_x e mov_y di conseguenza.
  • Altro codice. Potresti metterli in un array, ma questo significherebbe perdere la possibilità di aggiornarli uno per uno e solo aggiornarli tutti o l'inizio dell'array, non il centro o la fine. Potrei sbagliarmi su questo, però.

Qualcuno potrebbe dirmi cosa mi manca?

Modifica: aggiunto il mio shader di seguito.

#version 330

layout (location = 0) in vec2 pos;
layout (location = 1) in vec3 clr_in;

uniform float osclx, oscly, osina, ocosa, omovx, omovy;
uniform float msclx, mscly, msina, mcosa, mmovx, mmovy;
float oldx, oldy, x, y;

out vec3 clr_out;

void main() {
    x = pos.x;
    y = pos.y;

    x = x * oscly;
    y = y * osclx;
    oldx = x;
    oldy = y;
    x = oldx * ocosa - oldy * osina;
    y = oldx * osina + oldy * ocosa;
    x = x + omovx;
    y = y + omovy;

    x = x * msclx;
    y = y * mscly;
    oldx = x;
    oldy = y;
    x = oldx * mcosa - oldy * msina;
    y = oldx * msina + oldy * mcosa;
    x = x + mmovx;
    y = y + mmovy;

    gl_Position = vec4(x, y, 0.0f, 1.0f);
    clr_out = clr_in; }
    
posta Marius Macijauskas 17.10.2015 - 13:23
fonte

3 risposte

7

Anche se penso che i lati positivi che hai fornito possano essere veri, c'è un particolare vantaggio per le matrici che penso sia importante: quasi tutte le trasformazioni che si vogliono fare nella grafica - ridimensionamento, rotazione, traduzione, ecc. - possono essere rappresentato come moltiplicazione della matrice. È bello avere un formato comune, un'interfaccia, se vuoi. Inoltre, le composizioni di operazioni possono anche essere rappresentate come una singola matrice. Quindi, se vuoi eseguire un ridimensionamento, una rotazione, un ridimensionamento, una traslazione e una rotazione, è pur sempre una sola matrice. Questa è una vittoria piuttosto grande. Questo non vuol dire che i singoli tipi di trasformazione non possano essere conservati "sul lato" nella gerarchia degli oggetti sottoposti a rendering, ecc. - essere in grado di regolare il "mov_x" è davvero prezioso - ma la pipeline grafica tende a dipendere dalle matrici internamente .

    
risposta data 17.10.2015 - 15:43
fonte
6

Ci sono diversi buoni motivi per rappresentare le trasformazioni come matrici:

  1. I vettori sono utilizzati molto nella grafica 3D;
  2. Le matrici sono strutture dati efficienti per memorizzare più vettori;
  3. La moderna pipeline grafica è basata su shader e richiede all'applicazione client di inviare rapidamente i dati (ad esempio i buffer);
  4. Il client può usare una chiamata di singola funzione per inviare la matrice di trasformazione ad una uniforme singola nel vertex shader, mentre l'approccio proposto richiederebbe più divise indipendenti di vertice e il client per emettere chiamate di funzione multiple prima di raggiungere qualcosa come glDrawArrays o equivalente - che mantiene la GPU inattiva più a lungo e la rende meno efficiente
  5. La matematica è più semplice da eseguire e meno incline all'errore rispetto all'approccio proposto (confronta il tuo shader complicato rispetto a qualcosa di più semplice come gl_Position = projection_matrix * view_matrix * model_matrix * position_vector;
  6. Con le matrici, puoi accumulare trasformazioni in una singola matrice e ridurre il numero di operazioni matematiche in modo significativo in molti casi (ad esempio gl_Position = pvm_matrix * position_vector;

In definitiva, penso che sia sbagliato pensare di essere più efficiente. Le operazioni matematiche per tradurre / ruotare / ridimensionare saranno le stesse indipendentemente da come le guardi, e il tuo codice sembra molto più complesso di quanto dovrebbe essere. Perché dovresti (o peggio, quelli che mantengono il tuo codice) tenere traccia di 16 uniformi per una matrice 4x4 (e fare chiamate OpenGL per inviare dati per ognuna) quando potresti tenere traccia di 1 uniforme e avere una singola chiamata OpenGL per matrice? Non vorrei lavorare su quel tipo di codice.

Inoltre, molta efficienza nella grafica 3D deriva dal parallelismo della GPU e dalla sua capacità di consumare rapidamente i dati. L'hardware è già ottimizzato per gestire alcuni casi comuni e l'utilizzo di matrici come struttura dati per archiviare le trasformazioni è così comune che hanno i propri tipi di dati incorporati in GLSL (ad esempio mat4 ). È come chiedere "Perché i modelli 3D sono sempre costruiti usando triangoli quando invece potrei usare la forma geometrica

risposta data 18.10.2015 - 14:55
fonte
0
  • La semplicità. Un sacco di codice è noioso e gli shader di scrittura richiedono flessibilità. Ho fatto l'ottimizzazione che hai appena mostrato in passato e tutto ciò che ha fatto è stato ferirmi e darmi mal di testa.

  • parallelismo. Non sto dicendo che la GPU lo fa, ma offre sicuramente l'opportunità di ottimizzarlo. Con tutte queste istruzioni la GPU non ha idea di cosa stai facendo e non sarà mai in grado di fare alcuna ottimizzazione da sola.

Tenete a mente che la GPU è una bestia che schiaccia il numero progettata per motori AAA scritti pigramente, ed è truccata contro tali ottimizzazioni fatte in casa. Il cambiamento non è ancora all'ordine del giorno dei produttori o di chiunque altro perché la tecnologia è ancora in evoluzione e gli standard vengono costantemente riscritti.

Basta scaricare la matrice e lasciare che la macchina imbrogli un po 'per te.

    
risposta data 23.10.2016 - 23:44
fonte

Leggi altre domande sui tag