Progetto Di GraficaGalleria Borromini di Palazzo Spada a RomaRiproduzione del modello ottico in grafica 3DRealizzato da: Roberto Valenti
Indice
IntroduzioneLa galleria Borromini (anche conosciuta come galleria prospettica) è il frutto di studi matematici ed architettonici del Borromini in collaborazione con il padre. A rendere questa galleria famosa è l'effetto ottico che essa produce: la sua lunghezza sembra essere superiore ai 30 metri, mentre non ne supera i 9. Questo progetto prende in considerazione la galleria come potrebbe apparire all'occhio e non il modello reale che lo produce. Della galleria verrà dunque solo ripreso lo stile architettonico cercando di interpretare al meglio il modello virtuale partendo da una sua foto. I pacchetti software utilizzati per questo scopo sono, come da specifiche di progetto, xcmodel, xcsurf e xcrayt, quindi sono state utilizzate alcune soluzioni non ottimali per realizzare alcuni effetti (come ad esempio superfici booleane). Il Colonnato
Le "barrette" che compaiono al di sopra e al di sotto dei capitelli (barra#up.db e barra#down.db) non sono altro che la prosecuzione dei capitelli stessi e sono state create con lo stesso metodo usato per la creazione della base, in quanto non era possibile creare una superficie spigolosa e rotonda nella direzione di rotazione senza andare a toccare i CP (Control Point). Dopo averle posizionate (Fig. 3) è stata generata la parte alta del colonnato utilizzando sempre la stessa tecnica (top.db). La curva è stata creata con il pacchetto xccurv per poter riuscire ad avere una maggior flessibilità nel cercare di rendere questa superficie il più possibile simile a quella originale. Dopo aver posizionato anche quest'ultima superficie il colonnato è completo (Fig. 4).
L'arco
Per poter realizzare l'arco caratteristico dell'arcata si è utilizzata una superficie tubolare creata replicando una linea (curva piana) nella traiettoria di un semicerchio. Naturalmente il semicerchio di traiettoria e quello utilizzato per lo skinning coincidono, in modo da poter mantenere un match perfetto tra le due superfici. Nella Fig. 6 si può vedere il risultato della combinazione di queste 3 superfici appena create.
La superficie nella figura 6 è stata creata interattivamente con xcsurf, creando una base di CP rettangolare sull'asse xy, e modificando successivamente le altezze di ogni CP sull'asse delle z. La superficie, propriamente copiata, traslata e scalata, costuitirà i rilievi primari dell'arco (abbellimento.db, abbellimento2.db, portante.db) visibili in Fig. 7 . Utilizzando lo stesso procedimento utilizzato per top.db (la parte alta del colonnato) si è realizzata la parte alta dell'arco (tettoarco.db). Si è scelto di non comlpletare l'arco in tutti i suoi lati in quanto non utile e non visualizzabile ai fini alla resa.
Per realizzare il contorno dell'arco (archiabb.db, Fig 11) è stato utlizzato lo stesso semicerchio impegnato nella costruzione dell'arco, ripetuto sulla traiettoria di una curva ondulata. Per la stella (stellaleft.db, stellaright.db) è stata disegnata una curva rappresentante la sua proiezione, poi è stata copiata, scalata al massimo e spostata leggermente in avanti. Un successivo skinning delle due shape ottenute dà luogo alla mesh in Fig.10, da replicare e posizionare sull'arco.
Il risultato finale, in wireframe ed in shading , è mostrato nelle figure 12 e 13.
Altri OggettiGli altri oggetti impiegati sono per lo più muri (muroleft.db, muroright.db, muroup.db, muroback.db) e pavimenti (pavement.db, floor.db), che sono stati realizzati traslando e scalando cubi nella giusta posizione. Inoltre ci sono altri due oggetti, la cornice del quadro (cornice.db) e lo scalino (scalino1.db, scalino2.db) che appare davanti ai primi due colonnati. La cornice è stata ottenuta tramite una curva rettangolare chiusa rappresentante il bordo interno, copiata e scalata per ottenere il bordo esterno. Utilizzando lo strumento "InBetween" sono state create altre 3 copie posizionate all'interno delle 2 shape che sono state spostate avanti ed indietro per creare la forma della cornice. Lo scalino non è altro che una solita superficie di rotazione generata da una curva, ma i CP di un lato sono stati scalati fino a raggiungere la forma di una linea, per poi essere spostati al centro dell'asse di rotazione. Naturalmente la parametrizzazione di questo oggetto non è ottimale, ma non avendo a disposizione altri strumenti questa soluzione è stata considerata accettabile. Le figure 14 e 15 mostrano i wireframe degli oggetti descritti.
La scenaUna volta creati tutti gli oggetti si è passati alla composizione della scena utilizzando la libreria "descriptor". Il listato di questo passo è disponibile nell'Appendice A. La figura 16 mostra la scena in fase di realizzazione.
Le prossime immagini mostrano la scena finita e guardata da diverse inquadrature, renderizzata con raytrace a 2 livelli.
Appendice A (listato del codice c per la creazione della scena)#include "descriptor/descriptor.h" int main(void) { ITEM commonattribute,white; ITEM colonnato1,colonnato2,colonnato3,colonnato4,colonnato5,colonnato6, colonnato7,colonnato8,arco1,arco2,arco3,arco4,floor,pavement, muroleft,muroup,muroright,muroback,scalino1,scalino2,quadro,cornice; ITEM scene; // SETTAGGIO LUCI E AMBIENTE set_background(0.1,0.1,0.1,TRUE); set_ambient_light(0.9,0.9,0.9,0.7); create_distant_light(-0.5,-0.5,-0.3,1,1,0.9,1,"Distant"); create_point_light(2,3,6,1,1,0.9,1,3, "light1"); create_point_light(2,0,1,1,1,0.9,1.5,10, "light2"); create_point_light(2,-6,1,1,1,0.9,1.5,5, "light3"); create_point_light(2,-12,1,1,1,0.9,1.5,5, "light4"); create_point_light(2,-18,1,1,1,0.9,1.5,5, "light5"); create_point_light(0,-20,2,1,1,0.9,1.5,20, "light6"); // ATTRIBUTI commonattribute = create_attribute("commonattribute"); set_color(commonattribute,0.89,0.76,0.65,0.1,0.8); set_reflectivity(commonattribute,0.1,10); white = create_attribute("white"); set_color(white,0.95,0.95,0.95,0.2,0.8); set_reflectivity(white,0,0); // LETTURA OGGETTI DELLA SCENA muroleft = read_nurbs("muroleft.db"); muroup = read_nurbs("muroup.db"); muroright = read_nurbs("muroright.db"); muroback=read_nurbs("muroback.db"); floor = read_nurbs("floor.db"); pavement= read_nurbs("pavement.db"); scalino1=read_nurbs("scalino.db"); scalino2=read_nurbs("scalino.db"); quadro=read_nurbs("quadro.db"); cornice=read_nurbs("cornice.db"); colonnato1 = read_obj("colonnato.obj", "colonnato_1"); colonnato2 = create_copy(colonnato1, "colonnato_2"); colonnato3 = create_copy(colonnato1, "colonnato_3"); colonnato4 = create_copy(colonnato1, "colonnato_4"); colonnato5 = create_copy(colonnato1, "colonnato_5"); colonnato6 = create_copy(colonnato1, "colonnato_6"); colonnato7 = create_copy(colonnato1, "colonnato_7"); colonnato8 = create_copy(colonnato1, "colonnato_8"); arco1 = read_obj("arco.obj", "arco_1"); arco2 = create_copy(arco1, "arco_2"); arco3 = create_copy(arco1, "arco_3"); arco4 = create_copy(arco1, "arco_4"); // TEXTURE MAPPING/SET ATTRIBUTE set_attribute(colonnato1,white); set_attribute(colonnato2,white); set_attribute(colonnato3,white); set_attribute(colonnato4,white); set_attribute(colonnato5,white); set_attribute(colonnato6,white); set_attribute(colonnato7,white); set_attribute(colonnato8,white); set_attribute(arco1,white); set_attribute(arco2,white); set_attribute(arco3,white); set_attribute(arco4,white); set_attribute(cornice,commonattribute); set_projection_texture(muroright,commonattribute,"wall.hr",1,1,0.5,0.5); set_projection_texture(muroup,commonattribute,"wall.hr",1,1,0.5,0.5); set_projection_texture(muroleft,commonattribute,"wall.hr",1,1,0.5,0.5); set_projection_texture(pavement,white,"pavement.hr",2,0,0.5,1); set_projection_texture(floor,commonattribute,"wall.hr",2,1,0.5,0.5); set_projection_texture(muroback,commonattribute,"wall.hr",2,1,0.5,0.5); // POSIZIONAMENTO OGGETI NELLA SCENA set_scale(muroright,1,10,1); set_scale(muroup,0.55,10,0.66); set_scale(muroleft,1,10,1); set_scale(muroback,1.3,1,2); set_translate(muroright,0,-12,0); set_translate(muroup,3.5,-12,4); set_translate(muroleft,4,-12,0); set_translate(muroback,5.5,-25,-2.5); set_translate(quadro,4.5,-24,-0.5); set_translate(cornice,4.5,-24,-0.5); set_projection_texture(quadro,white,"galleria.hr",1,2,0.5,0.5); set_scale(pavement,1,10,1); set_translate(pavement,2,-8,0); set_scale(floor,6.5,20,1); set_translate(floor,2,-8,-2.1); set_translate(scalino2,4,0,0); set_translate(colonnato2,4,0,0); set_translate(colonnato3,0,-6,0); set_translate(colonnato4,4,-6,0); set_translate(colonnato5,0,-12,0); set_translate(colonnato6,4,-12,0); set_translate(colonnato7,0,-18,0); set_translate(colonnato8,4,-18,0); set_scale(arco1,0.9,0.9,0.9); set_translate(arco1,2,-0.2,2.5); set_scale(arco2,0.9,0.9,0.9); set_translate(arco2,2,-6,2.5); set_scale(arco3,0.9,0.9,0.9); set_translate(arco3,2,-12,2.5); set_scale(arco4,0.9,0.9,0.9); set_translate(arco4,2,-18,2.5); // CREAZIONE SCENA scene = create_list(colonnato1, "scene"); scene = insert_in_list(scene,colonnato2); scene = insert_in_list(scene,colonnato3); scene = insert_in_list(scene,colonnato4); scene = insert_in_list(scene,colonnato5); scene = insert_in_list(scene,colonnato6); scene = insert_in_list(scene,colonnato7); scene = insert_in_list(scene,colonnato8); scene = insert_in_list(scene,arco1); scene = insert_in_list(scene,arco2); scene = insert_in_list(scene,arco3); scene = insert_in_list(scene,arco4); scene = insert_in_list(scene,floor); scene = insert_in_list(scene,pavement); scene = insert_in_list(scene,muroleft); scene = insert_in_list(scene,muroup); scene = insert_in_list(scene,muroright); scene = insert_in_list(scene,muroback); scene = insert_in_list(scene,quadro); scene = insert_in_list(scene,cornice); scene = insert_in_list(scene,scalino1); scene = insert_in_list(scene,scalino2); save_scene("progetto.md","scene_progetto",scene); return(0); } |