Tessere isometriche

Rendering con Pov ray


Non mi assumo nessuna responsabilita' per danneggiamenti, perdita di dati o danni personali come risultato diretto o indiretto dell'uso delle informazioni contenute in queste pagine. Questo materiale e' fornito cosi' com'e' senza nessuna garanzia implicita o esplicita.


Home
Hardware
Software

Ultimamente mi e' ripresa la scimmia per i giochi isometrici, quelli come Populous, Syndicate o Ufo, tanto per capirci. Invece di glissare come faccio di solito, ho deciso di affrontare la questione in modo piu' costruttivo: e' possibile generare le tessere necessarie ad un gioco isometrico con Pov ray?

Sembra che la risposta possa essere si. Per il momento non ne ho ancora una certezza piena, sono solo riuscito a piazzare la camera in modo decente e ho preparato questo script base.

	      background { color rgb <1,0,1> }

	      light_source { <0,100,0> color rgb <1,1,1> }
	      
	      camera
	      {
	        orthographic angle 50
		location <186,153,-186> 
		look_at <0,0,0>
	      }

	      // tile surface
	      box
	      { 
		<-100, 0,100>
		< 100,-1,-100>
		pigment { color rgb <0,0,0> }
	      }
	    
base

La scena ha bisogno di una leggera post produzione prima di poter essere considerata una iso tessera a tutti gli effetti:

	povray +FN5 +Obase.png +W80 +H60 -D0 base.pov
	mogrify -crop 76x40+2+10 base.png
      

Questo e' un esempio di come sia possibile generare blocchi di pietra isometrici che possiono essere utilizzati come pavimentazione di miniere e dungeon. Per aumentare la resa ho utilizzato una isosurface; premetto che non ho una grande esperienza di pov-ray, quindi il risultato e' certamente migliorabile.

#include "functions.inc"
#include "colors.inc"

background{color rgb <1,0,1>}
//background{color rgb <0,0,0>}

// posiziona la camera
#switch(View)
  #case(0)
    camera
    {
      orthographic
      angle 64
      location <18.6, 8.0,-18.6> 
      look_at  < 0  ,-7.3,  0  >
      translate <0,-0.4,0>
    }
  #break
  #case(1)
    camera
    {
      angle 50
      location <20,16,-20> 
      look_at <0,-5,0>
    }
  #break
#end

light_source { <20,30,-8> White }


// pavimento della tessera
isosurface
{
  function
  {
    f_rounded_box(x,y,z,
    		1.2,				// raggio di curvatura
		10,8,10)			// size in x,y,z
    + pow(f_agate(x/15,y/15,z/15),4) * f_bozo(x/12,y/12,z/12) * 1.0
    + f_bozo(x/18,y/18,z/18) * 1.2
  }
  contained_by
  { 
    box
    { 
      <-12, 10,-12>, 
      < 12,-10, 12> 
    } 
  }
  max_gradient 6.0
  accuracy 0.005
  texture 
  { 
    pigment
    { 
      bozo
      scale 5.0
      turbulence 1.1
      color_map
      {
	[ 0.0 color rgb <0.29,0.24,0.18> ]
	[ 0.5 color rgb <0.57,0.48,0.37> ]
	[ 1.0 color rgb <0.70,0.55,0.40> ]
      }
    }
    finish
    { 
      roughness 0.1
      ambient 0.25		// parte in ombra 
      diffuse 0.75		// parte in luce
      crand 0.02		// effetto sabbia
    }
  }
  translate <0,-8.0,0>
}
	    
rock block rock block rock block

Il risultato finale si puo' ammirare qui sotto.

result

Lo spazio tra i blocchi e' dovuto alla funzione f_bozo che deforma l'intero blocco: oltre a rendere le pareti del blocco non perfettamente lisce ne riduce leggermente le dimensioni. Sarebbe possibile ridurre questo effetto riducendo l'ampiezza della funzione f_bozo oppure modificandole la curvatura in modo che abbia un valor medio minore di 0.5.
Il risultato mi sembra comunque accettabile.

Aggiungo qui alcune note sulla composizione delle immagini perche' sono sicuro di dimenticare tutto: come comporre le tessere in un'unica immagine e rendere trasparente lo sfondo viola.

        montage block_[1-3].png -tile x1 -geometry 60x59+0+0 row.png
	mogrify -transparent '#ff00ff' row.png
      

Ho provato ad aggiungere delle pareti a sasso sopra un pavimento fatto di pietre, il risultato sono le tessere qui sotto.

rock block rock block rock block  
rock block rock block rock block rock block
rock block rock block rock block rock block
rock block rock block rock block  

Mi sono permesso di montare queste tessere in un piccolo labirinto, il risultato mi sembra niente male.

tiles example

Engine grafico

Dopo diversi anni ho ripreso in mano questo lavoro e mi sono chiesto: "Ma perche' non fare veramente un engine grafico isometrico?"

Chiaramente non e' la prima volta che succede una cosa del genere, sara' almeno la 1000-esima volta che esco con una proposta del genere e puntulmente non si conclude un bel niente.

Questa volta ho provato un approccio piu' soft: "Come dovrebbe funzionare un engine grafico per giochi isometrici?"
Ho tentato di analizzare diverse configurazioni, il risultato puo' essere ancora affinato ma a me comincia a dare una certa soddisfazione (contrariamente alle altre volte).

tiles stack

Supponiamo di dividere il mondo in strati di spessore omogeneo, ciascuno strato puo' avere un'altezza diversa dagli altri, ma almeno per il momento, non puo' avere variazioni al proprio interno. Dall'alto applichiamo una griglia a maglie quadrate che tagli tutti gli strati che compongono il nostro mondo. Otteniamo la situazione mostrata nella figura precedente: se consoderiamo una singola posizione sulla mappa abbiamo tutti gli strati impilati uno sull'altro.

Come si disegna questa roba?

La risposta piu' semplice sta' nell'algoritmo del pittore. Conviene dipingere per prima la tessera piu' nascosta e poi procedere fino a quella in primo piano. Secondo questo principio si procede dal basso verso l'alto impilando tutti gli strati.

Ora un'altra domanda: "Meglio procedere verticalmente o orizzontalmente?"

Mi spiego meglio: partiamo da una tessera ed impiliamo tutto quello che ci sta sopra o prima completiamo il primo strato e poi passiamo allo strato superiore?

isometric view

Questa e' la vista isometrica del nostro mondo, sopra alle caselle disegnate saranno impilati i vari strati del mondo. Secondo il mio modestissimo parere conviene procedere per strati: partendo dal fondo viene completato tutta la base, poi si stende lo strato sopra questa e cosi' via.

scan lines

Il disegno procede per scan lines diagonali, ad ogni passaggio tutta una diagonale della mappa viene depositata sulla scena principale; la scansione procede dal punto piu' lontano verso l'osservatore.

rendering process

L'animazione qui sopra mostra la sequenza di deposizione delle tessere nella scena principale.

Questa tecnica permette alcuni speed-up: il singolo layer puo' essere realizzato a parte dalla scena principale e solo in seguito applicato per intero alla scena principale, se all'interno del layer non ci sono movimenti non e' necessario il rebuild del layer stesso.

Ora qualcuno comicera' a chiedere: "Ma l'engine grafico dov'e'?"
Al momento non c'e' ancora, per il momento ho solo realizzato uno script in grado di generare l'animazione sottostante, volevo essere sicuro che non nascessero difetti o sovrapposizioni sbagliate tra le tessere procedendo in questo modo.

man walk animation

Ok, lo ammetto: non mi sono impegnato molto nella realizzazione dello sprite!
A mio favore vorrei sostenere che mi premeva verificare l'algoritmo, l'omino e' passato un po' in secondo piano; inoltre pac man si renderizza facilmente senza troppo sbattimento (e riempie molto bene il volume dedicato alla singola tessera).

Il buon funzionamento sembra confermato, ora non resta che rimboccarsi le maniche...

Prima di lanciarmi nella sempre troppo lunga stesura di un engine grafico ho voluto fare ancora qualche esperimento rubando tessere isometriche qua e la e montandole insieme. Il risultato e' un piccolo kit che potete utilizzare per fare degli esperimenti, chiaramente genera solo immagini statiche.

In questo esempio ho varcato la soglia, infranto le regole, superato ogni limite ed ho provato alberi fuori misura! Non ho mai creduto nelle tessere irregolari, cioe' quelle tessere che non sia inscritte nel parallelepipedo standard; invece mi devo ricredere: non vale tutto, ci sono delle sottili regole a cui bisogna sottostare o si rischiano dei grossi errori durante il movimento dei personaggi, ma con una certa attenzione e' possibile mescolare tessere con volumi differenti. Nell'esempio qui sotto gli alberi hanno una larghezza decisamente superiore alla piastrella standard ed altezze irregolari.

garden example

minos walk animation


Download: render.sh
base.pov
blocks.tar.gz
walls.tar.gz
isometric_tcl-0.02.tar.gz
isokit-0.01.tar.gz
minos_pack-0.01.tar.gz

Questo sito e' stato realizzato interamente con vim.
Grazie a tutta la comunita' open source, alla free software foundation e chiunque scriva software libero.