Approfondimenti
di Michael J. Hammel traduzione di Antonio Cartelli

BMRT

    Parte 1ª: Dedicato al neofita - Creazione, visualizzazione in anteprima e rappresentazione finale di semplici immagini
  1. Introduzione
  2. Programmi per l'utilizzatore - Programmi per la rappresentazione e la visualizzazione in anteprima delle immagini
  3. Programmi per lo sviluppatore - librerie, compilatori, ecc
  4. Scenari di esempio
  5. Il File di input - il formato RIB
  6. Primi passi
  7. Ombreggiatori
  8. Conclusioni
indent
indent

1. Introduzione

      Un paio di anni fa, immediatamente dopo l'uscita del film Toy Story, ho iniziato a raccogliere quante più informazioni potevo trovare sulla computer grafica. Inizialmente mi sono interessato per lo più ad informazioni di carattere generale; più tardi, quando ho visto che tipo di software esisteva per i sistemi Windows e Mac, mi sono riproposto di vedere se esistevano pacchetti analoghi, per la rappresentazione e la modellizzazione tridimensionale, che girassero su sistemi Unix. Il primo pacchetto che ho incontrato è stato POV-Ray, che per le sue caratteristiche è stato trasportato su varie piattaforme incluso un discreto numero di sistemi Unix. Con lui ho trovato anche altri pacchetti tra i quali Polyray e Radiance. Poiché non avevo alcuna esperienza di pacchetti 3D ho deciso di partire con POV-Ray in quanto c'era disponibilità di un gran numero di informazioni on-line (la maggior parte delle quali è stata trasferita su Internet), c'era un folto gruppo di persone che frequentava il newsgroup comp.graphics.rendering.raytracing ed era possibile procurarsi diversi testi stampati. Quest'ultimo elemento è stato per me quello determinante, in quanto avevo bisogno di documentazione che non dovessi stampare da me, che fosse organizzata abbastanza bene e che potessi leggermi durante l'ora di pranzo nei giorni lavorativi.


Figura 1: Uno scenario campione creato utilizzando BMRT. Il testo è stato realizzato utilizzando il pacchetto font3d, che può generare file RIB in uscita.

      Non molto tempo dopo aver scoperto il POV-Ray mi è capitato di incontrare un altro pacchetto chiamato BMRT. Il BMRT è a tutt'oggi un insieme di pacchetti che sono conformi alle specifiche dell'interfaccia RenderMan. Queste specifiche sono le stesse utilizzate da PRMan, il pacchetto usato dalla Pixar per realizzare Toy Story. Sebbene desiderassi imparare molto di più su BMRT, all'epoca non avevo quelle conoscenze che, in quanto prerequisiti, mi consentissero di comprendere come utilizzare tale pacchetto. La documentazione di POV-Ray, dal canto suo, mi ha permesso di apprendere alcuni dei concetti di base della disciplina. Dopo circa un anno di lavoro svolto con POV-Ray, mentre nel contempo effettuavo continue ricerche in altri campi della computer grafica, ho pensato di rivolgermi, ancora una volta, a BMRT. Ora riesco a comprendere molto meglio ciò che è in grado di fare per cui è giunto il momento di imparare ad usarlo.

      Nel primo articolo di questa trilogia su BMRT intendo descrivere il contenuto del pacchetto ed introdurre gli elementi di base sull'utilizzo delle funzioni del BMRT. Va sempre e comunque tenuto presente che gran parte della terminologia che verrà utilizzata potrebbe essere completamente nuova e che proprio per questo i primi elementi e le prime descrizioni potrebbero non essere pienamente comprensibili. Vi prego di perdonarmi, ma vi assicuro che descrivere un pacchetto così potente come il BMRT e le relative specifiche RenderMan in un articolo introduttivo non è affatto cosa facile. Devo dire comunque che l'impresa non mi spaventa.
Nel corso di questo articolo cercherò di illustrare in dettaglio il contenuto del pacchetto. Anche se questo non vuole essere un corso di formazione completo ed onnicomprensivo, sarà sicuramente sufficiente a consentirvi di muovere i primi passi. Non appena avrete finito dovrete procurarvi le specifiche del RenderMan dalla Pixar. Si tratta di una descrizione di ciò che il BMRT implementa ed è scritta molto bene ed in maniera facile da seguire. Fornisce inoltre una guida di riferimento necessaria a comprendere i collegamenti C e RIB all'interfaccia RenderMan.

Che cos'è il BMRT?

      BMRT sta per Blue Moon Rendering Tools (Programmi per la rappresentazione grafica "Luna Blue"). È un insieme di pacchetti e librerie create da Larry Gritz, che ora lavora alla Pixar, che consentono di visualizzare in anteprima e rappresentare modelli e scenari tridimensionali. Il motore di rappresentazione (programma) e le librerie statiche (usate per creare applicazioni che possono generare file RIB in uscita) sono tutti compatibili con lo standard di interfaccia RenderMan sviluppato dalla Pixar. Il RenderMan non è, allo stato attuale, nessuno dei componenti software, sebbene molte persone utilizzino indifferentemente i termini RenderMan e PRMan (l'implementazione software delle specifiche RenderMan). Si tratta di specifiche che fissano le modalità di comunicazione di un sistema di modellizzazione con un sistema per la rappresentazione. BMRT è un'implementazione del sistema di reppresentazione dotato di una libreria statica da utilizzare con sistemi per la modellizzazione, che comprende anche singoli programmi specifici.
      I pacchetti per la rappresentazione compresi in BMRT, consentono di tracciare raggi, di gestire l'irraggiamento luminoso, le sorgenti luminose per area, i retini e le applicazioni d'ambiente, la gestione programmabile delle ombre nel linguaggio degli ombreggiatori RenderMan, il movimento sfuocato, le ombre proiettate automaticamente da raggi, la CGS (Geometria Solida Costruttiva), la profondità di campo, ed in più fornisce supporto ad ombreggiatori di solidi e gestori di immagini, ed ha altre caratteristiche avanzate. Il pacchetto contiene anche veloci ed agili visualizzatori RIB in anteprima (che usano OpenGL e X11) per permettere "test a matita" di scenari ed animazioni.

La versione corrente e dove reperirla

      Nel momento in cui ho iniziato a scrivere queste pagine, il 22 febbraio 1997, la versione più recente di BMRT era la 2.3.5. Ottenibile dal sito Web BMRT (http://www.seas.gwu.edu/student/gritz/bmrt.html). In questo sito si possono trovare anche immagini di esempio e riferimenti ad altri siti Web che si occupano di RenderMan. Larry consente di procurarsi soltanto versioni precompilate dei rappresentatori, delle librerie RIB e degli ombreggiatori. Egli, comunque, fornisce diversi ombreggiatori in formato sorgente insieme alla loro versione compilata. Ci occuperemo degli ombreggiatori più avanti. Le versioni di BMRT sono disponibili per Larry non intende trasferire BMRT su sistemi operativi non Unix per una serie di problemi logistici (accesso alle macchine e così via) che coinvolgono anche lo sviluppo sulle diverse piattaforme. Al momento non è prevista compatibilità con la distribuzione MkLinux. Non so neanche se Larry intende lavorare alla compatibilità con Alpha Digital o con qualche altro Linux non Intel.

Cosa c'è nel pacchetto?

      Il pacchetto in distribuzione comprende tutto ciò che potremmo considerare come un insieme di programmi per l'utente, un insieme di programmi di sviluppo e documentazione per entrambi. Non sarebbe corretto riferirsi a quanto appena descritto come a pacchetti per l'utilizzatore o per lo sviluppatore, a causa della natura stessa dei pacchetti, ma, nell'ambito di questo articolo una tale classificazione è di aiuto per una migliore organizzare della presentazione.

Programmi per l'utente - Rappresentatori e visualizzatori d'anteprima (Renderers and Previewers)

      Sono i programmi che consentono all'utente di effettuare le operazioni appena descritte e consistono di: È sicuramente più agevole ricordare che questi pacchetti sono quelli che consentono di rappresentare schizzi o versioni finali degli scenari che si vanno a realizzare. I primi due sono usati, in generale, per rappresentare bozze, l'ultimo per rappresentare lo scenario definitivo. In ogni caso essi non servono a creare i file degli scenari; questi ultimi, infatti, contengono la descrizione degli oggetti che costituiscono lo scenario stesso. Tali file utilizzano un formato detto RIB, che sta per formato Bytestream dell'Interfaccia RenderMan. I file degli scenari possono essere creati a mano (pratica non molto comune), mediante la scrittura di un programma C che utilizzi i pacchetti di sviluppo descritti nella sezione seguente, o mediante l'uso di modellizzatori che producano in uscita file di formato RIB.
      I file RIB descrivono la forma e la posizione degli oggetti, per cui si può dire che forniscono una geometria della scena, anche se non descrivono i colori degli oggetti, i retini sulla superficie degli oggetti, e gli aspetti connessi all'illuminazione della scena stessa. Queste ulteriori informazioni diventano patrimonio del RIB mediante l'uso di "ombreggiatori" (shaders), che sono file esterni che descrivono l'aspetto degli oggetti nella scena. Nel pacchetto di sviluppo sono presenti poi programmi per la creazione e l'esame dei file di ombreggiatura.

Programmi per lo sviluppatore - librerie, compilatori, ecc

      Il software BMRT per lo sviluppatore è costituito da un insieme di librerie e file di intestazione che consentono all'utente di creare programmi C che producono in uscita file RIB o che analizzano i file sorgenti di ombreggiatura. I programmi d'utente possono essere progettati ad hoc per la creazione di una singola scena o di riprese o possono essere parte di sistemi di modellizzazione più generali quali sono AC3D o SCED. Sempre nel pacchetto dedicato allo sviluppatore sono compresi programmi per la compilazione di file sorgenti di ombreggiatura che producono in uscita file in formato .so e programmi per l'analisi dei file compilati di ombreggiatura in grado di ricavare il loro tipo, i parametri ed i valori iniziali.
      I file sorgenti di ombreggiatura somigliano molto all'ordinario codice C. Il file sorgente viene compilato e trasformato in uno di diverso formato cui ci si riferisce usualmente come file di tipo .so. Le versioni compilate .so sono in effetti file ASCII. È evidente che la notazione .so può essere fuorviante per l'utente familiare con la creazione di librerie di ombreggiatura, ma va tenuto presente che queste ultime non sono file compilati (e quindi oggetto) di ombreggiatura. I file .so sono dei puri e semplici file di testo.
Si noti che il software in distribuzione non viene fornito con librerie linkabili per i rappresentatori.

Documenti

      Con quanto viene fornito nel pacchetto in distribuzione ci sono unicamente due file di documentazione, entrambi ben scritti e ricchi di riferimenti. Il primo è una descrizione dettagliata di tutti i pacchetti e del come utilizzarli; ciò rappresenta un riferimento inestimabile per i neofiti che vogliono apprendere come ottenere quanto più possibile dai programmi imparando ad utilizzare i parametri da passargli a riga di comando. Il secondo è una rapida introduzione all'API RenderMan e contiene una breve descrizione del formato RIB. Per ottenere informazioni più dettagliate sul formato RIB si deve contattare la Pixar chiedendo la versione ufficiale 3.1 delle Specifiche dell'interfaccia RenderMan. Sebbene il documento delle specifiche non sia scritto a livello di corso introduttivo contiene informazioni dettagliate, secondo lo stile di una guida di riferimento, sul formato dei file RIB. Per ulteriori informazioni sul come contattare la Pixar, si vedano le FAQ cgr.renderman o le FAQ di comp.graphics.renderman rispettivamente agli indirizzi:
http://www.seas.gwu.edu/student/gritz/cgr.renderman.faq
http://www.cis.ohio-state.edu/hypertext/faq/usenet/graphics/renderman-faq/faq.html


2. Programmi per l'utilizzatore - Rappresentatori e visualizzatori di anteprima

rendribv - rappresentatore d'anteprima reticolare

      Il primo dei rappresentatori rendribv, consente la visualizzazione di anteprima dei file di scenario in input in forma reticolare. Le visualizzazioni di anteprima mostrano le primitive geometriche senza ombreggiature e senza che siano rimosse le linee nascoste. Una visualizzazione reticolare usa una gabbia a reticoli ("wire cages") per rappresentare gli oggetti invece di visualizzarli come oggetti solidi costituiti da superfici. La rappresentazione reticolare richiede l'uso del sistema a finestre X11. Rendribv ha diversi parametri che possono essere dati a riga di comando, ciascuno dei quali è illustrato nella documentazione a corredo. Un aspetto importante, di cui ricordarsi, è che rendribv è stato progettato per visualizzare una o più inquadrature di un file RIB. Esso offre un buon metodo per visualizzare in anteprima animazioni senza il sovraccarico che normalmente accompagna la gestione di luci ed ombre sulle superfici di oggetti. Lo scenario di esempio limbo.rib fornisce un esempio di animazione. Sul mio 486DX2/66 con 40Mb di memoria l'animazione reticolare ottenuta con rendribv è abbastanza lenta. Sul mio laptop con P75 ed 8 Mb di memoria è sicuramente più veloce.

rgl - veloce visualizzatore di anteprima a poligoni che poggia su OpenGL

      Un altro visualizzatore d'anteprima fornito con il pacchetto in distribuzione è il programma rgl. Questo rappresentatore visualizza in anteprima immagini di superfici di oggetti con semplici ombreggiature di Gouraud, utilizzando OpenGL (OpenGL è un insieme di specifiche per interfaccie grafiche messo a punto dalla Silicon Graphics - si veda la rassegna dei libri di questo mese che concerne il testo: "Programmazione OpenGl con il sistema X Window" di Mark Kilgards). L'ombreggiatura di Gouraud è una tecnica che aiuta ad eliminare forti variazioni di intensità cromatica che possono causare strisce o sbandieramenti. Con tale programma vengono rimosse anche le linee nascoste, ovvero quelle linee e superfici che non dovrebbero essere visibili in quanto coperte da altre linee o superfici. Poiché rgl richiede OpenGL, occorre che una apposita versione della libreria OpenGL sia disponibile su una determinata piattaforma affinché Larry possa trasferire rgl su quella stessa piattaforma. Fortunatamente la libreria MesaGL è disponibile in ambiente Linux, così come lo sono alcune versioni commerciali delle librerie ufficiali OpenGL, per cui c'è una versione di rgl per Linux. La rgl è linkata staticamente per cui non si ha bisogno di alcuna delle librerie MesaGL o OpenGL per poterla utilizzare. Altre versioni di BMRT per Unix potrebbero, però, non avere questo programma.

rendrib - rappresentatore di alta qualità w/traccia di raggi e irraggiamento luminoso

      Questo programma è come il cacio sui maccheroni. Rendrib è un rappresentatore dotato di tutti gli attributi, conforme a RenderMan, in grado di fornire non soltanto l'intero insieme delle caratteristiche dettate dalle specifiche RenderMan ma anche cose come: traccia di raggi, irraggiamento luminoso, modellizzazione solida, profondità di campo, movimento sfuocato, sorgenti luminose di area, funzioni di retino, funzioni d'ambiente, ombreggiatori per solidi e immagini, ed il supporto del linguaggio di ombreggiatura RenderMan. L'ultima versione supporta anche una funzione di spostamento, una tecnica di rappresentazione di un'immagine su una superficie che oltre a modificare l'aspetto della superficie trasforma anche la struttura della superficie stessa. Rendrib è il programma da utilizzare allorché si va a visualizzare uno scenario definitivo per ottere il meglio delle sue caratteristiche, ovvero i risultati più realistici rispetto a quelli ottenuti fino a quel momento.

Qualche parola sulla compatibilità con distribuzioni commerciali di Linux

      La versione 2.3.4 del pacchetto di rappresentazione BMRT è stata realizzata con la versione 26 della libreria g++. La versione 2.3.5 è stata linkata con la versione 27 della g++. Ritengo che non ci siano problemi ad utilizzare le versioni commerciali più recenti di Linux perché la versione 27 è stata rilasciata da un bel po' e dovrebbe pertanto trovarsi su tutte le versioni di Linux più recenti. Sul mio laptop, ad esempio, ho una vecchia versione di Slackware 3.0 sulla la quale dispongo unicamente di g++ v26, ne consegue che su questa macchina non sono in grado di mandare in esecuzione i rappresentatori v2.3.5. Per me questo non è un grande problema ma è bene che quelli di voi che vogliono provare ad esplorare BMRT ne tengano debitamente conto. Non so se Larry consente di procurarsi anche versioni più vecchie di BMRT per cui coloro che vogliono poter utilizzare la distribuzione più recente di BMRT devono provvedere ad aggiornare il proprio sistema.
      Si noti che se le librerie X e MesaGL/OpenGL sono state linkate staticamente ai rappresentatori, le librerie C/C++ sono ancora linkate dinamicamente, per cui occorre porre molta attenzione alla versione di queste librerie che viene utilizzata.


3. Programmi per lo sviluppatore - librerie, compilatori, ecc

slc - compilatore del linguaggio delle ombreggiature

      Il precedente è un programma che riceve in ingresso i file sorgenti scritti usando le regole del linguaggio delle ombreggiature, quelli con estensione .sl per intenderci, li compila trasformandoli nelle versioni oggetto, che sono poi quelle con estensione .so. I file così compilati sono a tutti gli effetti codice a livello di linguaggio macchina e vengono utilizzati dal rappresentatore rendrib per determinare come applicare giochi di luci ed ombre ad un determinato oggetto (non ne sono sicuro al cento per cento, ma mi sembra un'ipotesi ragionevole). RenderMan è un'interfaccia procedurale mentre gli ombreggiatori sono procedure scritte in un linguaggio simile al C. Devono essere compilati per essere utilizzati con un rappresentatore conforme a RenderMan quale può essere BMRT. Il compilatore delle ombreggiature trasforma le descrizioni procedurali in un formato che il rappresentatore è poi in grado di gestire.
      Gli ombreggiatori si presentano in varie forme: ombreggiatori superficiali che definiscono le modalità con le quali si presenta la luce che parte da un punto su di un oggetto, ombreggiatori solidi che fissano le caratteristiche della luce allorché passa attraverso un oggetto (quale può essere l'atmosfera), ombreggiatori luminosi che descrivono le modalità di illuminazione di una scena, ombreggiatori di spostamento, ombreggiatori di trasformazione, ombreggiatori di immagini, e così via. rendrib supporta tutti questi tipi di ombreggiatori.
      Il pacchetto BMRT viene fornito insieme ad un numero notevole di ombreggiatori, alcuni dei quali sono espressamente richiesti dalle specifiche RenderMan, mentre altri sono stati aggiunti da Larry come un dono in aggiunta ad alcuni scenari di esempio.

RenderMan richiede i seguenti ombreggiatori Ombreggiatori aggiuntivi forniti con scenari di esempio
constant (costante), matte (opaco) metal (metallico), shinymetal (metallico splendente) plastic (plastico), paintedplastic (di plastica dipinta) ambientlight (luce ambiente), distantlight (luce lontana) pointlight (punto luce), spotlight (luce riflessa) depthcue (vena profonda), fog (nebbia) bumpy (offuscato), null background (sfondo), clamptoalpha, dented (dentellato), funkyglass (vetro fumé), glass (vetro), gmarbltile_polish (piastrella lucida di marmo), noisysmoke (fumo turbolento), parquet_plank (parquet), plank (tavola), screen (schermo), screen_aa, shiny (splendente), stucco, wallpaper_2stripe (carta da parati), wood2 (legno),
luci d'area - ombreggiatore per sorgenti luminose di area
Per tutti questi ombreggiatori sono disponibili sia le versioni compilate che il codice sorgente.

Si noti che i file .so disponibili sono le versioni precompilate dei corrispondenti file .sl e che i file .so non sono compatibili con il software Renderman della Pixar PRMan, mentre lo sono i file sorgenti .sl. La ragione di ciò è da ricercarsi nei metodi utilizzati rispettivamente da rendrib e PRMan per generare immagini 3D. Per ulteriori informazioni si veda la sezione relativa alle Incompatibilità con PRMan nel documento bmrt.html che si trova nell'area doc del pacchetto in distribuzione.

sotell - elenca gli argomenti di un ombreggiatore compilato

Altro pacchetto collegato agli ombreggiatori è sotell. Esso consente ad un utente di analizzare un file di ombreggiatura compilato in modo da determinarne il tipo, la lista dei parametri ed i valori settati di default. L'utilità di una tale funzione sarà evidente nel prossimo articolo che si occuperà della scrittura degli ombreggiatori. Toccheremo brevemente l'argomento nel seguito di questo articolo parlando dell'utilizzo degli ombreggiatori predefiniti.

libribout.a, ri.h - libreria RenderMan per la creazione di file RIB

Questi due file sono utilizzati dagli sviluppatori che hanno bisogno di scrivere applicazioni che producano in uscita dei file RIB. Si tenga presente che i file RIB sono i file di input (compresi i riferimenti agli ombreggiatori) che vengono passati al programma rendrib. Ci sono due modellizzatori che possono generare i file RIB che interessano, SCED e AC3D, anche se, in qualche circostanza, può essere conveniente scriversi personalmente delle funzioni specializzate che generino una serie di riferimenti specifici. In tal caso (o se si è abbastanza ambiziosi da decidere di realizzare un proprio modellizzatore) si può linkare il proprio programma alla libreria libribout.a. Il programma che si sta realizzando dovrebbe allora utilizzare il collegamento, mediante il C, all'API RenderMan. Questa API è descritta, anche se non molto dettagliatamente in verità, nel file di documentazione poets.ps già citato. Una descrizione migliore si trova invece nel testo The RenderMan Companion (Il manuale RenderMan) di Steve Upstill pubblicato dalla Addison-Wesley. Coloro che vogliono scrivere applicazioni utilizzando l'API RenderMan devono poi includere nei loro file sorgenti anche il riferimento al file di intestazione ri.h.

libsoargs.a, so.h - analizzatori di parametri per ombreggiatori compilati

Secondo quanto riportato nella documentazione proposta da Larry (che è tutto ciò che ho per le mani, non avendo mai analizzato personalmente l'applicazione PRMan), con il pacchetto PRMan della Pixar è distribuita anche una libreria linkabile per l'analisi degli ombreggiatori compilati, un po' come avviene per il programma sotell nel pacchetto BMRT. Poiché le versioni compilate degli ombreggiatori nei due pacchetti differiscono per i loro formati, Larry ha provveduto a distribuire un'analoga libreria da utilizzare con le applicazioni che devono analizzare le sue versioni dei file di ombreggiatura compilati. Applicazioni che necessitino di una tale funzione devono includere nel loro codice sorgente il file di intestazione so.h ed essere linkate con la libreria libsoargs.a.

4. Scenari di esempio

Nel pacchetto in distribuzione ci sono 8 scenari di esempio che vengono descritti nel file README della directory degli esempi, ma per completezza li descriverò brevemente anche qui. Si tratta di: Mentre alcuni di questi esempi sono ottimi per apprendere la sintassi e la struttura di un file RIB, altri non lo sono affatto. Per imparare qualcosa sul legame (binding) RIB-ASCII si deve partire dall'analisi degli esempi seguenti: I rimananenti esempi RIB non sono ben formattati (probabilmente a causa del fatto che sono il prodotto di un modellizzatore o di un programma linkato con libribout.a). Quasi sicuramente, però, non è di alcuna utilità esaminare tutti questi file RIB in quanto il loro scopo principale è illustrare le caratteristiche del linguaggio di ombreggiatura. In tali casi occorre dare un'occhiata agli ombreggiatori che vengono utilizzati, anche se si deve comunque controllare il RIB per sapere quali ombreggiatori sono importanti per un dato esempio. Valga per tutti il caso del file tpdisp.rib che fornisce un esempio di applicazione di ombreggiatori di spostamento, per la quale basta cercare nel RIB i comandi di spostamento per sapere quale file sorgente di ombreggiatura di spostamento esaminare.
      Per spiegare in maggior dettaglio come si usano questi programmi utilizzerò due esempi per ciascuna delle rimanenti due sezioni di questo articolo. In alcuni di questi casi farò riferimento ad esempi che ho trovato nel Manuale RenderMan, in altri utilizzerò alcuni esempi di Larry o alcune delle mie esercitazioni iniziali. Certo non sono quanto di meglio ci si possa aspettare, ma questo articolo è stato per me un'occasione di apprendimento né più né meno come per chiunque altro.

5. Il file di input - il formato RIB

Che cos'è?

Come già detto RIB sta per Bytestream dell'Interfaccia RenderMan. Lo si trova sia in formato ACII che codificato in binario. Qui analizzeremo solo la versione ASCII anche perché non ho quasi nessuna notizia sulla codifica binaria e BMRT non ha al suo interno alcun esempio di tal tipo. Tutti i file di esempio RIB sono in formato ASCII.
      Un file RIB non è altro che un file di testo, ASCII, costituito da una sequenza di comandi RIB. Questi comandi ricalcano quasi esattamente le loro controparti in termini di funzioni C dell'API RenderMan (ci sono alcune eccezioni con riferimento alla versione ufficiale delle specifiche). Se si scrive un programma C che effettui chiamate all'API RenderMan via la libreria libribout.a si ottiene in uscita la codifica ASCII della RIB. E' per questo motivo che è generalmente più facile usare i legami C con RenderMan piuttosto che scriversi un file ASCII con le specifiche RIB.

Qualcosa sul formato

Le semantiche dei due tipi di legame (C e RIB ASCII) sono molto simili. Entrambi hanno come argomenti coppie token/valore. Il legame C richiede che la lista dei parametri per le funzioni termini con NULL, il formato RIB ASCII no. I nomi delle procedure in C hanno per prefisso Ri mentre gli equivalenti comandi RIB non hanno questo prefisso.
      I file RIB supportano riferimenti a immagini singole o a riferimenti multipli di un'immagine, consentendo (come nell'esempio limbo.rib) di effettuare animazioni con la descrizione di una singola scena. Questo è un buon esempio di utilizzo di interfacce procedurali al RenderMan invece della realizzazione, a mano, di un file di codice RIB. È più facile prevedere la descrizione dello scenario attraverso un ciclo di programma che fare a mano i calcoli per determinare ogni riferimento utilizzando i comandi RIB ASCII.

Come si possono creare file RIB?

Ci sono tre modi per creare file RIB da utilizzare come input per un ombreggiatore BMRT:
  1. Scriverli manualmente
  2. Scrivere programmi C utilizzando l'API RenderMan e linkarli con libribout.a
  3. Utilizzare un modellizzatore
    In tal caso è bene sapere che ci sono tre modellizzatori attualmente disponibili per Linux che sono in grado di generare file in formato RIB:
L'impressione che mi sono fatto è che pochissima gente crei file RIB a mano, se non che per realizzare dei file di test per provare ombreggiatori o per qualcosa di simile. L'uso di modellizzatori in ambiente Linux è cosa abbastanza nuova per il grande pubblico per cui, a questo punto, ritengo che molti modelli vengano creati scrivendo programmi specifici per ogni scena e linkandoli poi con la libreria libribout.a. Si noti che è quasi certo che sarà presto disponibile il supporto allo sviluppo per AC3D, mentre si dice che per AMAPI sia venuta meno la trasportabilità su Linux. Per quanto riguarda SCED al momento non si sa nulla anche se, per circa un anno non ho visto alcun suo aggiornamento.
      Diamo ora un'occhiata ad un paio di esempi. Il primo è un semplice file RIB preso dagli esempi di Larry. Il secondo è un esempio di animazione facile facile, in sorgente C preso dal Manuale RenderMan.

Esempio 1a - Un esempio di file RIB

Il più semplice esempio del genere, agevole anche da scorrere, è preso dal kit BMRT in distribuzione ed è shadtest.rib. Esso contiene tre oggetti con retini (due sfere ed un piano tra esse) insieme ad una sorgente luminosa. Il listato sorgente è riportato nel Listato 1.
##RenderMan RIB-Structure 1.0
version 3.03
Display "balls1.tif" "file" "rgba"
Format 480 360 -1
PixelSamples 1 1
Projection "perspective" "fov" 45
Translate 0 -2 8
Rotate -110 1 0 0

WorldBegin

LightSource "ambientlight" 1 "intensity" 0.08

Declare "shadows" "string"
Attribute "light" "shadows" "on"
LightSource "distantlight" 1 "from" [0 1 4] "to" [0 0 0] "intensity" 0.8

AttributeBegin
#  Attribute "render" "casts_shadows" "none"
  Color  [ 0.7 0.7 0.7  ] 
  Surface "matte"
  Polygon "P"  [ -5 -5 0 5 -5 0 5 5 0 -5 5 0  ] 
AttributeEnd

AttributeBegin
  Translate -2.25 0 2
  Color [1 .45 .06]
  Surface "screen" "Kd" 0.2 "Ks" 0.8 "roughness" 0.15 "specularcolor" [1 .5 .1]
  Sphere 1 -1 1 360
AttributeEnd

AttributeBegin
  Translate 0 0 2
  Declare "casts_shadows" "string"
  Attribute "render" "casts_shadows" "shade"
  Color [1 .45 .06]
  Surface "screen_aa" "Kd" 0.2 "Ks" 0.8 "roughness" 0.15 "specularcolor" [1 .5 .1]
  Sphere 1 -1 1 360
AttributeEnd

AttributeBegin
  Translate 2.25 0 2
  Declare "casts_shadows" "string"
  Attribute "render" "casts_shadows" "shade"
  Surface "funkyglass" "roughness" 0.06
  Sphere 1 -1 1 360
AttributeEnd

WorldEnd
Listato 1: esempio shadtest.rib preso dal pacchetto BMRT

Elementi di interesse in questo file sono i seguenti:
  1. I valori posti prima del comando WorldBegin sono utilizzati per predisporre i parametri della macchina da ripresa e del display. Questi parametri globali sono noti come opzioni; le opzioni del display possono dipendere specificatamente dal rappresentatore utilizzato, quelle del rappresentatore non possono essere settate all'interno dei comandi WorldBegin/WorldEnd.
  2. Ci si riferisce ai valori posti all'interno dei comandi Attribute come ai parametri correnti, si tratta di parametri specifici degli oggetti come illuminazione, opacità, colori superficiali e retini.
  3. Oggetti (incluse le luci) creati all'interno dei comandi WorldBegin/WorldEnd esistono soltanto all'interno di tali comandi. Non ci si può riferire ad essi all'esterno di tali comandi.
  4. Va notato che i comandi RIB contengono serie di stringhe di caratteri e valori numerici. Ad esempio il comando surface è seguito dal nome della superficie (una stringa) seguita da una serie di coppie di token/valori. Questi token sono variabili note all'ombreggiatore che si va ad utilizzare ed i valori sono quelli che vogliamo assegnare a queste variabili nel momento in cui invochiamo l'ombreggiatore.
  5. Il segno # rappresenta un commento, ma il doppio # (ovvero ##) è un suggerimento per lo specifico rappresentatore. Per tutti gli scopi pratici anche questi sono commenti poiché nessun rappresentatore li usa per alcunché. Ritengo che il formato del tag di suggerimento sia cambiato nella versione 2.3.5 dei rappresentatori BMRT ma non so da cosa sia stato rimpiazzato.
  6. I comandi per creare le sfere sono ovvi. Il comando per creare un piano è "polygon". L'API RenderMan ed il BMRT forniscono il supporto per un certo numero di forme primitive. BMRT supporta anche la possibilità di combinare forme primitive in altre più complesse utilizzando una funzione nota con il nome di Geometria Solida Costruttiva.
  7. Il comando WorldEnd() fa sì che la scena venga inviata al display per la visualizzazione.
  8. I comandi RIB possono gestire linee multiple sebbene nell'esempio in considerazione ciò non venga mostrato.
Ho rimosso il commento all'inizio del file soltanto per guadagnare un po' di spazio. Dovreste leggerlo comunque e tentare di rappresentare questo esempio per rendervi conto di ciò che fa. Ciò che io mi sono ripromesso di fare con questo esempio è mostrare come è fatto un file RIB ASCII. Il formato del file dà un'indicazione della gerarchia dei comandi: WorldBegin/End racchiudono i comandi Attribute, che a loro volta racchiudono alcuni oggetti, i loro retini ed altre descrizioni. La comprensione di questa gerarchia aiuta a intravedere la portata di definizioni come quelle di oggetti o proiezioni. La gerarchia può essere ancora più evidente se si utilizza l'API RenderMan poiché il codice è scritto in linguaggio strutturato, il C.

Esempio 2a - Una semplice animazione in C

Il Manuale del RenderMan di Steve Upstill contiene un'apprezzabile quantità di codice di esempio che utilizza il legame del C con l'interfaccia RenderMan. Diamo un'occhiata al sorgente di uno dei seguenti esempi:
#include ""
#define NFRAMES    10    /* numero delle inquadrature nell'animazione */
#define NCUBES     5     /* # dei minicubi sui lati del cubo colorato */
#define FRAMEROT   5.0   /* # di gradi di cui ruotare il cubo tra le inquadrature */

main()
{
   int frame;
   float scale;
   char   filename[20];

   RiBegin(RI_NULL);      /* Fa partire il rappresentatore */

      RiLightSource("distantlight", RI_NULL);

      /* Visualizza la trasformazione */
      RiProjection("perspective", RI_NULL);
      RiTranslate(0.0, 0.0, 1.5);
      RiRotate(40.0, -1.0, 1.0, 0.0);

      for (frame = 1; frame <= NFRAMES; frame++)
      {
			sprintf(filename, "anim%d.pic", frame);
	 RiFrameBegin(frame);
	    RiDisplay(filename, RI_FILE, RI_RGBA, RI_NULL);
	    RiWorldBegin();
	       scale=(float)(NFRAMES-(frame-1))/(float)NFRAMES;
	       RiRotate(FRAMEROT * frame, 0.0, 0.0, 1.0);
	       RiSurface("matte", RI_NULL);

	       /* Definisce il cubo */
	       ColorCube(NCUBES,scale);
	    RiWorldEnd();
	 RiFrameEnd();
      }
   RiEnd();
}
Listato 2: shadtest.rib un esempio del pacchetto BMRT

Come si vede, la gerarchia dei comandi è ora un po' più evidente. Naturalmente, trattandosi di un'animazione anche l'esempio è un po' più complesso. Una sorgente luminosa distante è definita al di fuori di tutte le inquadrature dell'animazione. Il tipo di proiezione della fotocamera è definito insieme alla trasformazione di visualizzazione iniziale. Ciò è seguito dal ciclo principale che produce le inquadrature dell'animazione.
      All'interno del loop è definita ogni inquadratura. Il display è predisposto per scrivere su un file ed il formato dell'output è predisposto con RI_RGBA, a significare che verranno posti in uscita rosso, verde, blue e canali alfa (o in parole povere 3 colori ed 1 livello di opacità). Le modalità con cui ciò si realizza sono specifiche a seconda del rappresentatore.
      Questo esempio particolare è semplificato dall'uso di una routine esterna, ColorCube(), che definisce, nel caso specifico, la geometria dell'oggetto da utilizzare. In questo caso mediante ColorCube() viene costruito un cubo con le facce colorate. Ho lasciato questa routine come esercizio per il lettore, soprattutto perché ho sempre desiderato poterlo dire a qualcuno. Per coloro che non hanno la pazienza di aspettare il momento in cui riescono ad elaborarlo da soli, il codice di ColorCube() si trova nel Manuale del RenderMan.

6. Primi passi

Il punto precedente ci ha permesso di vedere come si presenta un file RIB e come lo si possa creare: sappiamo che abbiamo bisogno di un file RIB come input agli ombreggiatori forniti con il pacchetto BMRT, sappiamo che i file RIB forniscono la geometria di uno scenario o di un insieme di inquadrature e che gli ombreggiatori sono referenziati dai file RIB al fine di realizzare retini per gli oggetti presenti in quegli scenari.
      Bene, che dobbiamo fare? Vediamo di analizzare in tutti i suoi passi un esempio che preveda tutte le fasi relative ad un singolo scenario: dalla creazione, all'ombreggiatura, alla visuallizzazione d'anteprima fino alla rappresentazione finale.

Creiamo il file RIB

Ecco un esempio facile facile che ho creato da me: si tratta di un sorgente C linkato alla libreria libribout.a. Una volta in esecuzione produce il file RIB di una scena con una sfera blue su un piano grigio, illuminata da una singola sorgente luminosa distante. Il sorgente è commentato per cui si può vedere esattamente ciò che ho fatto per creare lo scenario. Il sorgente C è nella stessa directory degli esempi (o in ogni altra directory al disotto della directory principale del pacchetto in distribuzione). Per compilare questo programma si devono utilizzare i seguenti comandi:
gcc -o exampl2a -O exampl2a.c -I../include ../lib/libribout.a
Per mandare in esecuzione il programma basta scrivere
exampl2a > exampl2a.rib
A questo punto si dispone del file di input ASCII RIB da dare in pasto ad uno dei programmi di rappresentazione.

Veduta d'anteprima dello scenario con rendribv e rgl

La prima cosa da fare è esaminare la scena utilizzando una visualizzazione reticolare, per essere sicuri che ci siano tutti gli oggetti voluti. Forse non saremo in grado di dire se sono allineati in maniera corretta (uno di fronte all'altro o uno di seguito all'altro) ma saremo sicuramente in grado di vedere se la loro forma è corretta e se sono nel campo di vista. Per vedere in anteprima l'immagine si dia il seguente comando: rendribv exampl2a.rib
Benissimo, tutto si presenta come dovrebbe. Abbiamo ottenuto una sfera ed un piano. Aggiungiamo qualche superficie agli oggetti utilizzando rgl. La sfera deve prendere l'aspetto solido ed essere blue mentre il piano deve essere di color grigio.
      Per vedere in anteprima lo scenario si usi il seguente comando:
rgl exampl2a.rib
Figura 2: la rappresentazione a reticoli prodotta da rendribv

Rappresentazione completa con rendrib

Ancora una volta, ci siamo quasi. Il disegno che state vededo non è molto grande a causa della tecnica che ho utilizzato per catturare l'immagine e convertirla in un file GIF. Ma il risultato che si può vedere è all'incirca quello che mi aspettavo. Il piano è un po' scuro ma andiamo a vedere ciò che otteniamo dal rappresentatore di alta qualità
      Per vedere la scena in anterpima con rendrib si usi il seguente comando:
rendrib exampl2a.rib
Figura 3: l'immagine prodotta da rgl
A quanto pare la sfera è ben illuminata nella parte alta mentre il piano non lo è affatto. Probabilmente ciò ha a che fare con l'illuminazione degli oggetti.

Sistemiamo l'illuminazione

Nel file sorgente di esempio avevo messo una sorgente luminosa distante su una retta tracciata da <0.0, 10.5, -6.0> a <0.0, 0.0, 0.0>, e questo per far in modo che la luce cadesse solo sulla metà più alta della sfera. Ciò non spiega però come mai il piano non sia visibile. Il problema è altrove. Il sorgente C della scena in esame contiene le seguenti righe:
RiLightSource(RI_DISTANTLIGHT, RI_INTENSITY,
      &intensity, RI_FROM, (RtPointer)from,
      RI_TO, (RtPointer)to, RI_NULL);
Figura 4: l'immagine prodotta da rendrib
Le variabili from e to definiscono la linea sulla quale si trova la sorgente luminosa distante. Per rendere questa luce più brillante sulla superficie della sfera possiamo spostare il punto to fino alla coordinata -600 sull'asse delle z. Questa luce illuminerà la sfera molto meglio ma il piano è ancora invisibile. Possiamo anche provare ad incrementare il valore della variabile intensità portandola da 0.6 a 1.0.
      A questo punto viene da chiedersi: che c'è di sbagliato nel piano? dove è andato a finire? La risposta è nel retino superficiale utilizzato.

Test con gli ombreggiatori standard

La versione originale della scena di esempio utilizzava per il piano un ombreggiatore di superficie opaco (matte). Quando la superficie veniva rappresentata con la singola sorgente luminosa distante la riflettività della superficie la rendeva di fatto invisibile almeno all'angolo di vista che avevamo predisposto con la nostra traslazione iniziale.
Un primo tentativo è consistito nell'aggiungere un punto luce sulla superficie, come si può vedere nella versione aggiornata del sorgente di esempio. Poiché non ne è venuto alcun effetto significativo ho tentato con un altro ombreggiatore - lo stesso ombreggiatore opaco (matte) usato sulla sfera. Voila! È venuta fuori la superficie, compreso il punto luce appena aggiunto. Che fortuna sfacciata!
Figura 5: Finalmente ecco il piano!

Diamo ora un'occhiata ad altri due esempi:
  • Un'altra sfera piena sopra un piano con un muro dietro
  • Lo stesso scenario con superfici retinate
Il file RIB per l' esempio 4a è probabilmente più semplice dell'esempio 2a anche se fornisce migliori risultati. La differenza consiste nell'uso di due punti luce disposti bene. Si ponga attenzione al modo in cui è definito il punto luce:
   LightSource "spotlight" 1 "from" [1 3 -4]
     "to" [0 0 0] "intensity" 15

È esattamente la stessa cosa che la luce distante usata nell'esempio 2a. Questa volta vengono usate due luci e si tratta di punti luce anziché sorgenti lontane. I punti luce disposti bene hanno come effetto un notevole realismo dell'immagine.

Figura 6: Esempio 4a (file jpg)

La prossima immagine è un po' più difficile da vedere. Non ho avuto il tempo di sistemare la brillantezza (ho utilizzato xv che mi ha insudiciato l'immagine e non ho avuto il tempo di rappresentare di nuovo il file RIB di Paul). Viene rappresentata la stessa scena della Figura 6 con la differenza che ora vengono applicati dei retini alla sfera, al muro ed al pavimento. Il retino sulla sfera è uno stucco trasparente. Il pavimento ha un retino tipo legno ed il muro mostra l'effetto carta da parati. La sfera è interessante per il fatto che utilizza un ombreggiatore superficiale tipo vetro con un'applicazione di spostamento tipo stucco. L'applicazione di spostamento altera la forma della sfera causando il leggero effetto protuberanza (abbastanza) visibile nella Figura 7. Tutti i retini appaiono evidenti dall'esame del file RIB. Tutti gli ombreggiatori utilizzati in questo esempio sono disponibili nella versione 2.3.5 di BMRT. Si lascia per esercizio al lettore diligente la rappresentazione e la modifica della brillantezza dell'immagine (che è, ancora una volta, una cosa che ho sempre desiderato di poter dire).

Figura 7: Esempio 4b (file jpg)

A questo punto sono rimaste da fare solo due cose:

È abbastanza facile, eccettuato il fatto che la prima delle due potrebbe richiedere un intero articolo a parte e che, proprio per questo, nel seguito entreremo esclusivamente nel merito di cosa sono gli ombreggiatori senza di fatto approfondire come scriverli. Abbiate un po' di pazienza ed il prossimo mese vedremo insieme come scrivere ombreggiatori.

7. Ombreggiatori

Che cos'è esattamente un'ombreggiatore?

Secondo il Manuale del RenderMan,
Un ombreggiatore è la parte del programma di rappresentazione che elabora l'aspetto delle superfici visibili nello scenario. In RenderMan un ombreggiatore è una procedura scritta nel linguaggio delle ombreggiature RenderMan (RenderMan Shading Language) utilizzata per calcolare un valore o un insieme di valori (ad es. il colore di una superficie) necessari durante la rappresentazione.
Secondo me: un'ombreggiatore dà la superficie ad un oggetto.

Come si fa ad inserirlo in un file RIB?

Gli ombreggiatori sono procedure esterne cui fa riferimento a tempo di rappresentazione il motore di rappresentazione (in BMRT questo dovrebbe essere rendrib). Il legame del C con RenderMan chiama un'ombreggiatore con la funzione RiSurface. Le righe che seguono nel file sorgente di esempio utilizzato nella sezione precedente, applicano l'ombreggiatore opaco superficiale alla sfera ed al piano:
RiSurface("matte", RI_NULL); .
Si ottiene come risultato che la seguente linea viene aggiunta al file ASCII RIB prodotto dal programma allorché viene linkato con libribout.a:
Surface "matte" .
Ovviamente le cose possono risultare molto più complesse di quanto fin qui visto ma, almeno, si avrà la possibilità di riconoscere gli ombreggiatori nei file scenario di esempio.

Come compilare un ombreggiatore

Occorre avere sempre presente che gli ombreggiatori che uno scrive nel linguaggio degli ombreggiatori RenderMan (Shading Language) devono essere sempre compilati prima di poter essere utilizzati. La compilazione di un ombreggiatore è banale. Ad esempio per compilare l'ombreggiatore matte.sl e produrre il relativo file matte.so si deve scrivere la seguente riga:
slc matte.sl .

7. Conclusioni

Purtroppo, a tutt'oggi sulla Rete non ci sono ancora molte risorse dedicate a BMRT o RenderMan. La maggior parte di quanto è disponibile si può trovare a partire da L'emporio RenderMan - (http://pete.cs.caltech.edu/RMR/index.html). Una buona collezione di informazioni sugli ombreggiatori RenderMan è disponibile all'indirizzo: RManNotes - (http://www.cgrg.ohio-state.edu/~smay/RManNotes/index.html).
      E questo è quanto. Abbiamo esaminato gli elementi di base del pacchetto e ne abbiamo visto un'introduzione. Ora dobbiamo vedere come utilizzarli per farci qualcosa. Le pagine di Larry sul Web BMRT contengono numerosi link ad immagini molto interessanti create con BMRT, che dovrebbero rappresentare una buona motivazione al suo studio. Per quanto mi riguarda mi ci divertirò per tutto il mese prossimo cercando di apprendere il linguaggio delle ombreggiature Renderman per il numero della Musa della Grafica di Aprile. Se vi dovesse capitare di trovare qualcosa di interessante ritenetevi autorizzati ad inviarmi una nota.

indent
Informazioni per ordini:
Pixar Animation Studios
Attn: Katherine Emery
1001 W. Cutting Blvd.
Richmond, CA 94804
Specificare che si sta ordinando "Le specifiche RenderMan". Il suo costo è $20 USA. È bene notare che non ho nulla a che fare con la Pixar (ma posso sognare, o no?).
Upstill, Steve The RenderMan Companion (Il Manuale RenderMan) A Programmer's Guide to Realistic Computer Graphics. Addison-Wesley 1992
Le procedure di interfaccia RenderMan® ed il protocollo RIB sono © Copyright 1988, 1989, Pixar. Tutti i diritti sono riservati. RenderMan® è un marchio registrato della Pixar.

Blue Moon Rendering Tools sono © Copyright 1990-1995 di Larry I. Gritz. Tutti i diritti sono riservati.

indent

[ La pagina della Musa ] [ Indice ]


Per l'articolo originale: © 1997 Michael J. Hammel - Pubblicato sul n. 15 della Linux Gazette
Per l'edizione italiana: © 1997 A. Cartelli - Pubblicato sul n. 4 di LGEI a cura del LUGBari