Illuminazione in Irrlicht

by Santostefano “Blizzard” Giovanni
contact: idmgiovanni@libero.it

NEL SEGUENTE TUTORIAL POTETE TROVARE ERRORI DI CASE SENSITIVITY NELLA SCRITTURA DELLE FUNZIONI AD ESEMPIO clearzBuffer sarebbe clearZBuffer. QUESTO PERCHE' IL PROGRAMMA DI VIDEOSCRITTURA CORREGGE A VOLTE AUTOMATICAMENTE. VISIONATE QUINDI I SORGENTI ALLEGATI PER LA PRECISIONE

scarica il seguente tutorial in formato PDF

PREMESSA

Salve, vi ricordate di me? (domanda d'obbligo, dato che non vedete i miei tutorial da un bel po di tempo). Riprendiamo il nostro piccolo discorso sull'irrlicht parlando questa volta dell'illuminazione della scena. Il processo di lighting è una cosa molto importante nell'industria videoludica e se non altro è uno dei punti di forza del fotorealismo dei motori grafici. In questo tutorial esploreremo il sistema di illuminazione fornito dall'irrlicht, scoprendo come può essere utilizzato all'interno del vostro codice. Classi, metodi e membri da descrivere sono davvero pochi, pertanto non avrete di fronte a voi un megatutorial… ^_^

PROCESSI DI ILLUMINAZIONE

Credo che la maggior parte delle persone che stia leggendo questo articolo è a conoscenza del fatto che l'illuminazione di un poligono è un processo che avviene via hardware (riferendosi al gergo della computer grafica), ovvero gestito da un hardware dedicato allo scopo: nel nostro caso la scheda video. Tuttavia, originariamente la computazione dell'illuminazione di ogni singolo poligono veniva effettuata via software, un'operazione molto esosa per i gia' lenti processori di un tempo (il riferimento temporale è prima dell'uscita dei primi accelleratori grafici). L'illuminazione in generale si divide in due categorie principali:

• Per vertex lighting (pvl)
• Per pixel lighting (ppl)

La prima categoria è stata utilizzata sin dagli albori della computer grafica 3d, in quanto è un processo di illuminazione molto veloce, poiché è calcolata per ogni singolo vertice. Calcolare la luminosità di un vertice è in qualche modo come modificarne il colore originale (scurendolo o schiarendolo). L'illuminazione per vertice è molto approssimativa e nell'industria videoludica è stata sempre utilizzata solo per oggetti animati o comunque non statici. Per gli oggetti statici infatti si utilizzano le cosiddette lightmaps che sono texture checontengono luci ed ombre precalcolate maniera molto accurata; queste poi vengono blendate con la texture del materiale percreare un falso effetto luce statico (ma molto bello da vedere). Il secondo tipo di lighting (per pixel) è un sistema relativamente nuovo e nasce e si sviluppa di pari passo con lo sviluppo degli shader. Il sistema di illuminazione per pixel, calcola un valore di luminosità per ogni singolo pixel del poligono, aumentando di molto l'accuratezza dell'illuminazione. Irrlicht implementa entrambi i tipi. Tuttavia la ppl è disponibile solo con lo shader del normal mapping e quindi non è legata al normale utilizzo del motore che a livello di classi fornisce supporto per la sola illuminazione al vertice.

Pertanto è la pvl che descriveremo.

IRRLICHT LIGHTING

Una luce in irrlicht (dal punto di vista implementativo) non è nient'altro che un nodo della scena, pertanto gode delle proprietà di questi ultimi, come ad esempio valori posizionali ecc… e inoltre ha delle proprietà proprie. Ad esempio: state costruendo un giochetto alla Morrowind (non diciamo oblivion va! ) e state programmando l'effetto del vostro tizio che raccoglie una torcia del muro. Quando portate con voi la torcia, questa deve illuminare l'ambiente circostante… niente di più semplice! basta che sul bastone della torcia attacchiate la luce e il gioco è fatto, dato che la luce sarà posizionata sempre sul bastone

bastone->addChild(light);

Le luci calcolate in fixed pipeline sono generalmente 3:

•Omni Light
•Directonal Light
•Spot Light

Irrlicht implementa solo la omni e la directional light. La spotlight ovvero la luce tipo torcia elettrica (un cono di luce proiettato in una direzione) non è implemetata. La omni invece è una luce che si muove in tutte le direzioni, praticamente si sviluppa in una sfera. La direzionale è invece una luce senza attenuazione (praticamente infinita) che si muove in una sola direzione (un'ottima simulazione della luce solare!). Per creare una luce, utilizziamo ovviamente un metodo implemetato nello scene manager… e catturiamo il puntatore che questo metodo restituisce in un ILightSceneNode*.
Quindi creiamo il nostro nodo definiamo prima un puntatore:

ILightSceneNode* light;

Poi invochiamo il metodo dello scene manager

virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0,
const core::vector3df& position = core::vector3df(0,0,0),
video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f),
f32 radius=100.0f, s32 id=-1) = 0;

Parent al solito è il nodo genitore nell'albero della scena.
Position è la posizione della luce.
Color è il colore della radiazione diffusa della luce.
Radius è il raggio della sfera che segna l'area illuminata.
ID è il classico identificatore del nodo (se fate qualche query)

light->addLightSceneNode(0, core::vector3df(0,100,0), video::Scolorf(1.0f,0.0f,0.0f), 200.0f,1);

Questa riga crea una luce in posizione 0,100,0 ovvero sopra la nostra testa, di colore rosso (1,0,0)(r,g,b) di raggio 200 e con ID 1. Tuttavia vi avevo specificato di 2 tipi di luce… in questo caso abbiamo creato una luce omnidirezionale… ma quella direzionale?
Per fare questo dobbiamo accedere alla struttura dati che descrive la luce. La struttura dati è una struct SLight, definita nel file SLight.h . Definiamo quindi un reference a questa struttura:

video::SLight& ldata;

Ora utilizziamo un metodo descritto nell'interfaccia di classe ILightSceneNode

virtual video::SLight& getLightData() = 0;

questo restituisce appunto un riferimento(reference) ad una istanza di questa struttura dati

ldata = light->getLightData();

Da qui è possibile editare tutti i parametri della luce.

     //! Ambient color emitted by the light
     SColorf AmbientColor;    

     //! Diffuse color emitted by the light.
     /** This is the primary color you might want to set.     */
     SColorf DiffuseColor;          

     //! Specular color emitted by the light.    
     /** For details how to use specular highlights, see SMaterial::Shininess */
     SColorf SpecularColor;

Ovviamente la radiazione ambient, che sarebbe il colore che c'è anche in assenza di luce. Quella diffusa ovvero il colore che emana la luce e quella speculare, ovvero il colore di riflesso della luce.

//! Position of the light. If Type is ELT_DIRECTIONAL, this is the direction vector the light is coming from.
core::vector3df Position;

Position è la posizione della luce omnidirezionale oppure l'angolo della luce direzionale. L'angolo della luce direzionale è il versore di propagazione della luce(1). In pratica dovete passare il vettore direzione (lo ritroveremo nella gravità). Per esempio position=core::vector3df(0.0f,1.0f,0.0f); imposta una luce direzionale per puntare in alto verso il soffitto.

//! Radius of light. Everything within this radius be be lighted.
f32 Radius;

Radius è il raggio di azione di una luce omnidirezionale. Nella direzionale che è infinita ovviamente non vale…

//! Does the light cast shadows?
bool CastShadows;

Un booleano per decidere se la luce deve castare ombre (true) oppure no (false). Le ombre sono un argomento molto avanzato, quindi non ne parleremo in questo tutorial.

//! Type of the light. Default: ELT_POINT E_LIGHT_TYPE
Type;

L'ultimo parametro è un istanza della enum E_LIGHT_TYPE e può valere:

//! Enumeration for different types of lights
enum E_LIGHT_TYPE
{
    //! point light, it has a position in space and radiates light in all directions
    ELT_POINT,

    //! directional light, coming from a direction from an infinite distance
    ELT_DIRECTIONAL
};

ELT_POINT è la luce omnidirezionale (ovvero emettitore puntiforme). ELT_DIRECTIONAL è la luce direzionale. Vediamo ora un esempio su come settare una luce direzionale

video::SLight& ldata;
ldata = light->getLightData();
ldata.Type = ELT_DIRECTIONAL;
ldata.Position = core::vector3df(0,-1,0);

Questa luce direzionale punta al pavimento ovvero perfettamente in basso. Vediamo lo stesso esempio con un puntatore, se siete poco pratici dei reference:

video::SLight* ldata;
ldata = &light->getLightData();
ldata->Type = ELT_DIRECTIONAL;
ldata->Position = core::vector3df(0,-1,0);

Per vedere infine l'illuminazione sui vostri nodi, accertatevi di eseguire queste poche operazioni:

node->setMaterialFlag(video::EMF_LIGHTING, true);

Abilita l'illuminazione del nodo

node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);

Se scalate il nodo questo flag abiliterà il motore a rinormalizzare le normali dei poligoni in modo da evitare errori di calcolo della luce.

CONCLUSIONE

Siamo giunti alla fine di questo quarto appuntamento. Nei prossimi tutorial si intodurranno i materiali e i colori che completeranno l'utilizzo dell'illuminazione real time. Se al momento magari non ottenete i risultati che sperate pertanto attendere il tutorial sui materiali. Come sempre, se ho commesso errori concettuali, di trattazione o di codice, fatemelo sapere così da rendere sempre migliori i tutorial scrivo. Grazie per la lettura e arrivederci alla prossima puntata.

Santostefano “Blizzard” Giovanni
contact: idmgiovanni@libero.it


(1) Ringrazio Mobius per la correzione effettuata rispetto alla precedente versione


31 commenti per “Illuminazione in Irrlicht”

  1. paooolino ha scritto:

    Siccome l’argomento del tutorial non e’ affatto banale, ti segnalo un paio cose che sarebbe meglio spiegare per chi non capisce molto di grafica e motori 3d (come il sottoscritto)!

    “…Tuttavia la ppl è disponibile solo con lo shader del normal mapping e quindi non è legata al normale utilizzo del motore…”

    In breve, cosa sono gli Shader e il Normal Mapping?

    “…Le luci calcolate in fixed pipeline sono generalmente 3…”

    Cos’è questa fixed pipeline?

    ciao Blizzard!!

  2. Blizzard ha scritto:

    Gli shader, in maniera magari un po generale, sono programmi per le unità programmabili della scheda video.

    La scheda video possiede un hardware che sistematicamente svolge determinate operazioni sequenziali del tipo:
    Trasformazione dei vertici
    Illuminazione
    Texturing
    Rasterizzazione
    (Sono parecchio impreciso in questo!)
    Comunque diciamo che questa serie di operazioni vengono dette di fixed pipeline.

    Le moderne schede video, posseggono alcune unità hardware che bypassano totalmente questa sequenza di operazioni eseguendo quelle definite dall’utente:
    Sono (nel gergo coniato da ati/nvidia) i vertex shader (vector unit nella ps2) e i pixel shader.
    I primi accettano in ingresso un vertice, lo trasformano e poi lo restituiscono. I secondi accettano in ingresso un pixel lo trasformano e lo restituiscono.

    I programmi che l’utente scrive sono detti (come le componenti hardware) pixel e vertex shader in DirectX e fragment e vertex shader in OpenGL.

    Il normal mapping (generalizzazione della famiglia del bump e del parallax mapping ecc…) è una tecnica di simulazione di tridimensionalità di una superficie in base alla perturbazione delle normali di un poligono(data da una normal map) che crea un effetto di illuminazione che simula la rugosità di una superficie.

    Viene quindi utilizzato il calcolo della luminosità per ciascun pixel, inoltre la normal map (la texture in bianco e nero) si occupa di perturbare la normale di un poligono, in modo da non avere una illuminazione uniforme così da creare anche un self shadowing.

    Ritornando agli shader, fino ad ora era possibile solo accettare in ingresso un vertice e trasformarlo per poi restituirlo.
    La nuova generazione di schede video(con le DX10)
    daranno anche la possibilità di utilizzare i geometry shader che a quanto pare consentirebbero di fare cose abbastanza potenti come istanziare nuovi vertici ecc…
    (questa notizia l’ho beccata su qualche rivista… quindi da verificare).

    In ogni caso era scritto che in DX10 non ci sarà più la fixed pipeline, quindi in pratica non potrete più prendere una lista di triangoli(indici e vertici) e renderizzarla senza creare uno shader.
    Ovviamente verranno comunque forniti sistemi di base.

    Guardate quello che ho scritto con molta critica comunque! posso aver commesso anche errori concettuali

  3. Mancuso Raffaele ha scritto:

    preciso ke uno degli autori di irrlicht (hybrid) ha precisato sul forum ufficiale ke nella prosiima release (1.2) ci saranno le spot light

  4. Bellaz89 ha scritto:

    bello questo articolo, non c’è che dire e affronta il solito problema rognosetto delle luci.

    cmq le tue supposizioni sul geometry shader dovrebbero essere vere, anche io ho letto qualche cosa al riguardo, anche se non so assolutamente come faranno a implementarlo senza cambiare radicalmente la sintassi dei linguaggi ^___^.

  5. mestoppespert ha scritto:

    I’d prefer reading in my native language, because my knowledge of your languange is no so well. But it was interesting! Look for some my links:

  6. mestoppespert ha scritto:

    I’d prefer reading in my native language, because my knowledge of your languange is no so well.

  7. free leads ha scritto:

    mlm lead

  8. rourolold ha scritto:

    http://www.asstraffic.com/go/482826/1/9/n/ass-fuck ass fuckig ass fuck anal sex

  9. Coandalloca ha scritto:

    Hi there, my home page is http://www.google.com

  10. Agellurse ha scritto:

    http://ibis.uh.edu/Tools/Forum/forum1/713395154 youporn com , qknjs,

  11. ruffrorce ha scritto:

    http://jguru.com/guru/viewbio.jsp?EID=1520059 youporn

  12. Ascectisk ha scritto:

    http://blogcastrepository.com/forums/t/84662.aspx zootube , ssbffp, www.wanderlist.com/ejkfg you porn www.wanderlist.com/ejkfg youporn

  13. ruffrorce ha scritto:

    http://identi.ca/pornhubers porn hub , drao,

  14. Agellurse ha scritto:

    http://www.jacksonholewy.com/community/members/Pornhub-Full-Free-Videos.aspx pornhub , xsajnt,

  15. ruffrorce ha scritto:

    http://www.jacksonholewy.com/community/members/Redtube-Porn-Free-Full-Videos.aspx redtube com , putegia,

  16. Agellurse ha scritto:

    http://identi.ca/zootubes zootube animal porn , grgai,

  17. ruffrorce ha scritto:

    http://www.jacksonholewy.com/community/members/Redtube-Porn-Free-Full-Videos.aspx redtube com , xxmxa,

  18. ruffrorce ha scritto:

    http://blogcastrepository.com/members/kim-kardashian-sex-tape-kim-kardashian-naked.aspx kim kardashian sex tape, tqef,

  19. ruffrorce ha scritto:

    http://blogcastrepository.com/members/megan-fox-naked-megan-fox-nude.aspx megan fox naked, fuyu,

  20. Agellurse ha scritto:

    http://jguru.com/guru/viewbio.jsp?EID=1521385 redtube porn , nxmjmrh,

  21. ruffrorce ha scritto:

    https://fp.auburn.edu/gradschl/gscs/members/redtube-porn/default.aspx redtube, yyliyvg,

  22. Agellurse ha scritto:

    http://pdabooks.org/members/redtube-amateur.aspx redtube sex video , eytmhm,

  23. Agellurse ha scritto:

    http://community.republicanherald.com/members/redtube-amateur/default.aspx like redtube , wbwfcf,

  24. Ascectisk ha scritto:

    http://connections.blackboard.com/people/27fcfe2a09/profile redtube couples , xxqsa,

  25. ruffrorce ha scritto:

    http://www.asianave.com/redtubeples/ redtube wife , lkjeyxh,

  26. Agellurse ha scritto:

    http://somnib.us/forum/viewtopic.php?f=3&t=98504 zootube 350 , dbuluy,

  27. NeepMeteVob ha scritto:

    assfuck

  28. ruffrorce ha scritto:

    http://baumforum-nrw.de/viewtopic.php?f=2&t=594 sites like zootube , rgipn,

  29. NeepMeteVob ha scritto:

    dirty ass to mouth

  30. NeepMeteVob ha scritto:

    assfucking

  31. Ascectisk ha scritto:

    http://community.bsu.edu/user/Profile.aspx?UserID=4207 xxx redtube , fikjpme,

Lascia un commento