Want to make creations as awesome as this one?

Transcript

Intro

UGOLINI'S PROjecT

Simone Ugolini
+ Fattibile
+ Avevo già esperienza
Motore grafico
+ Fattibile
- Non ne sapevo molto
Intelligenza artificiale
- Assembly
- Troppo grande
Sistema operativo

Le idee

Blender
Blender
Software che esegue operazioni matematiche per rototraslare oggetti 3D e mostrarne il risultato in tempo reale

COS'È UN MOTORE GRAFICO

Ricavate le coordinate 2D si inizia il processo di rasterizzazione nel quale si verifica quali pixel sono all'interno del triangolo.
DA TRIANGOLO A PIXEL
I triangoli sono inizialmente descritti in uno spazio chiamato assoluto, queste devono essere poi transformate in spazio relativo alla camera (relToCam). Infine, le coordinate, ancora 3D, devono essere convertite in 2D (screen space), questo viene fatto grazie ad un processo chiamato proiezione.
TRASFORMAZIONI E PROIEZIONI
DA SPAZIO ASSOLUTO A RELATIVO

La nascita

Ugolini's graphic engine

Ok, ma se qualcuno l'ha gia fatto, perchè rifarlo?

Le librerie

"Non si può programmare un motore grafico in assembly"

cit: Qualsiasi persona sana di mente

#include "Windows.h"
Andando avanti
Print("cubo")
Quando ho iniziato
Meno possibili (progetto a scopo didattico)

Che librerie ho utilizzato?

Le prime risoluzioni
24Gennaio
I primi cubi
Importazioni di oggetti (.obj)
I primi bug
1Gennaio
24Febbraio
24Dicembre
22Dicembre
30Novembre
22Novembre

Motore grafico - cosa avevo già fatto

Prime prove di per-pixel shading
Luce speculare
Importazioni di materiali (.mtl)
2Marzo
11Aprile
1 Marzo
24Febbraio

Motore grafico - cosa avevo già fatto

grafica moderna

Per-pixel shading e la gpu

PERCHÈ FARLO DA CAPO?
+ Più realistico
- La mia CPU implorava pietà
- Serve una struttura del codice solida
+ Più realistico
- La mia CPU implorava pietà
- Serve una struttura del codice solida
- Non realistico
+ Computazionalmente "leggero"
+ Facile da implementare
- Non realistico
+ Computazionalmente "leggero"
+ Facile da implementare
Per-pixel shading
Per-triangle shading

I vantaggi di usare la gpu

- Lento trasferimento dati (deve passare per le PCI)
- Pochi processori ma molto potenti
-Tanti "processori" ma poco potenti
- Debuggare è un parto
- Codice da rendere parallelizzabile
+ Estremo calcolo parallelo
+ Adesso la mia CPU ha un amica con cui può implorare pietà insieme

Let's run it

No spoiler

Texture maps

4.0

NEW FEATURES

Ogni pixel all'interno del triangolo prenderà il valore della texture a coordinate UV, prodotte grazie all'interpolazione tra le coordinate UV dei vertici
Il materiale può avere una texture associata
Ogni triangolo ha associato un materiale e 3 punti chiamati UV

Textures

Textures

La mappatura richiede, oltre alle interpolazioni, una trasformazione spaziale (matrici)
Questi definiscono come, per ogni pixel, la luce riflette su di essi
Le normal map sono mappe contenenti vettori chiamati normali

NORMAL MAPS

Spot light
Spot light
Point light
Point light
Directional light
Directional light
LUCI
I tre tipi generali:
LUCI

Post processing

NEW FEATURES

4.1

Come funziona?

A cosa serve?

Consiste nel salvare i colori in floating point (-∞,+∞), invece che in uint8 (1 byte, 0->255)

L'HDR significa high dynamin range, o ampia gamma dinamica

Rende possibili alcuni effetti post-processing, quale il bloom

Aumenta il range di colori che si possono processare

HDR

REPEAT AND ADD

Ripeti il processo dalle 3 alle 11 volte e aggiungi i risultati

BLUR

Sfocatura

THRESHOLD

Tenuti i valori che superano una soglia

BLOOM

DOWNSCALE

Abbassamento risoluzione

Uno degli algoritmi più usati è l'ACES, io ho utilizzato una verisone semplificata sviluppata da Narkowicz
Il tonemapping serve per riportare il range dinamico (HDR) ad una scala di un byte (0->255)

TONE MAPPING

in breve :P

LA struttura

104 bytes
Vector2 uvCoordinates
Vector2 screenSpace_point
Vector3 bitangent
Vector3 normal,tangent

Vector3 relToCam_point

Vector3 absSpace_point

Fragment
28 bytes
16 bytes
8 bytes
12 bytes
200 bytes
Vector3 bitangent
Vector3 normal,tangent
Vector2 uvCoordinates[3]
Vector2 screenSpace_points[3]
Vector3 interpolationInfo[3]
Vector3 relToCam_points[3]
Vector3 absSpace_points[3]
GPU_Triangle
uint16 materialId
uint32 uvCoordinatesIds[3]
uint32 vertexIds[3]
float red,green,blue,alfa
float x,y
float x,y,z
TriangleId
RgbVector
Vector2
Vector3

Strutture dati generiche importanti

Gli attributi riguardanti il colore, come texture e coefficenti di riflessione verranno salvati a parte in strutture dati chiamate materiali

I punti verranno salvati in un array unico per tutti i triangoli, così come le coordinate UV

Caricare un nuovo triangolo

Per non salvare copie inutili degli stessi punti, i triangoli, inizialmente, salveranno solo l'indice (ID) dei punti e materiale associato, verranno copiati i valori di essi solo in seguito (primitive assembler)

Un triangolo ha diversi attributi: i punti in spazio assoluto, le coordinate UV e colore / texture.

ORGANIZZAZIONE DATI

200 byte
x3
Attributi per interpolazione
x3
x3
x3
x3
Punti sullo spazio relToCam/z (perspective corrected, 3D)
x1
x1
Attributi per normal maps
Normale, tangente, bitangente (3D)
Indice del materiale (materialId)
Attributi per texture
Coordinate spaziali
Coordinate UV (texture space, 2D)
Punti sullo schermo (screen space, 2D)
Punti in spazio relativo alla camera (relToCam space, 3D)
Punti in spazio assoluto (world space, 3D)

Gli attributi di un triangolo non sono pochi

TriangoLo

Triangolo figura geometrica composta da tre punti... giusto?

Processo logico

graphic pipeline

Punti, coordinate UV e triangoli (ID), vengono trasferiti sulla GPU
Cosa viene trasferito?

Trasferimento dati iniziale

Ok tutto, ma... come si transforma in codice?

Per passare da concetti a codice c'è bisogno di una solida organizzazione logica. Qui ho riportato un breve schema riguardante la gestione dei dati tra CPU - GPU

l'organizzazione logica - schema generale

DENTRO IL PROCESSO DELLA GPU

Questi triangoli verranno archiviati nell'array gpuSH.triangles
I triangoli una volta trasferiti sulla GPU, ancora sottoforma di TriangleId, vengono composti in una struct chiamata GPU_Triangle, che contiene copie dei punti e non più indici relativi all'array dei vertici

PRIMItive assembler

Qui i vettori di direzione, contenuti da luci direzionali e spotlight, vengono ruotati.
Le posizioni delle luci sono separate dal resto dei punti, necessitano quindi di una funzione a parte per la roto-traslazione da spazio assoluto a spazio relToCam.

Light rotation

Lo scopo di questo processo è processare i punti in spazio assoluto in modo da ottenerli in spazio relToCam.

Vertex shader

Questo è un grosso problema se si sta programmando in parallelo, dato che ogni triangolo avrà bisogno di 16 celle
Il clipping viene eseguito una volta per lato dello schermo, rendendo raro, ma possibile il caso in cui un solo triangolo generi 15 nuovi triangoli.
Eliminare parti di triangolo può dar luogo ad un poligono che deve quindi essere diviso in più triangoli.
Per questo motivo viene introdotto il clipping. Il clipping serve ad eliminare le parti di triangolo che escono dallo schermo.
I triangoli potrebbero parzialmente uscire dallo schermo. In questo caso il programma itererebbe comunque per ogni punto del triangolo risultando in migliaia di operazioni inutili.

CLIPPing

Verranno avviati 256 thread per triangolo, quindi 4 triangoli alla volta (per processore). Per ridurre i tempi i triangoli verranno processati in ordine diverso rispetto all'indice con cui
Una volta clippato, ogni triangolo viene suddiviso in quadranti e vengono avviati più thread per singolo triangolo.
RASTERIZZAZIONE

Per il calcolo del colore viene lanciato un thread per Fragment e il risultato (in float) viene archiviato della mappa rgb HDR

C'é altro?
FRAGMENT SHADER

Durante la rasterizzazione, il colore del pixel non viene calcolato: molti triangoli sono sovrapposti sarebbe uno spreco di risorse, si preferisce infatti salvarsi le informazioni per il calcolo del colore in strutture chiamate Frammenti e calcolare il colore alla fine

Thanks

Made by ugolini

Aiuto ;)
Fine