Possiamo dividere le ombre in due categorie: proprie e portate. Le ombre proprie sono quelle parti dei solidi che si scuriscono perché non colpite dalla luce. Le ombre portate sono invece le ombre proiettate da un solido.
L'uso delle ombre può risultare particolarmente dispendioso in termini di capacità di calcolo della macchina non soltanto per l'aggiunta di nuovi processi nella scena, ma anche perché i solidi che costruiamo per poter avere un effetto delle ombre soddisfacente devono essere sfaccettati il più possibile.
Se un piano è costruito da solo due triangoli ogni triangolo potrà essere in luce o in ombra e questo provoca che quando l'ombra avrà iniziato a coprire il piano si formeranno una serie di fastidiosi triangoli di diverse tonalità.
Papervision è una libreria OpenSource e quindi in continua evoluzione. Molte classi cercano di risolvere il problema di una netta divisione nella colorazione delle facce, ma ancora bisognerà aspettare prima di vedere un risultato che possa competere con un vero motore 3D.
Le ombre proprie possono essere costruite concettualmente in due modi: usando un materiale di per sè contenente il concetto di ombra o creando un materiale ombra da mischiare al nostro materiale di base.
La maggior parte delle classi che useremo per la realizzazione delle ombre è compresa nel package org.papervision3d.materials.shaders
.
FlatShader
È la classe più semplice e spesso più funzionale. Il suo algoritmo determina quanto una faccia è esposta alla fonte luminosa.
Costruttore di FlatShader
public function FlatShader( light:LightObject3D, lightColor:int = 0xFFFFFF, ambientColor:int = 0x000000)
GouraudShader
Cerca di creare un'ombra sfumata approssimando le zone d'ombra e quelle in luce.
Costruttore di GouraudShader
public function GouraudShader( light:LightObject3D, lightColor:int = 0xFFFFFF, ambientColor:int = 0x000000)
PhongShader
Per alcuni versi si comporta in modo simile a GouraundShader
, ma vi aggiunge a questo anche la possibilità di utilizzare una bitmap per simulare la granulosità del materiale. Il "bump mapping" può essere paragonato ad un bassorilievo, in questo caso soltanto illusorio, generato da zone di luce ed ombra.
Costruttore di PhongShader
public function PhongShader( light:LightObject3D, lightColor:int, ambientColor:int = 0x000000, specularLevel:int = 0, bumpMap:BitmapData = null, specularMap:BitmapData = null)
Miscelare Ombre e Materiali
Una volta creata la nostra ombra dobbiamo unirla al materiale per poter ottenere un'istanza di ObjectMaterial
applicabile al nostro solido
public function ShadedMaterial( material:BitmapMaterial, shader:Shader, compositeMode:int = 0)
In questo caso il materiale che stiamo creando utilizza una Bitmap di fondo e uno shader. Se non abbiamo bisogno di usare un bitmap, ma stiamo creando una superficie monocroma abbiamo a disposizione alcuni materiali equivalenti agli shader appena elencati. Questi sono FlatShadeMaterial
, GouraudMaterial
e PhongMaterial
.
La fonte di luce è sempre PointLight3D
, unica classe del package org.papervision3d.lights
.
Cotruttore di PointLight3D
public function PointLight3D( showLight:Boolean = false, flipped:Boolean = false)
Il punto luce è un'istanza di DisplayObject3D
per cui possiamo spostarlo nello spazio tramite x
,y
e z
, ma non abbiamo bisogno di aggiungerlo nella scena. Se decidiamo di aggiungerlo tramite addChild()
, avremo la possibilità di vedere il nostro punto luce a forma di prisma, ma è utile per lo più sui test. Possiamo vedere tutto il codice dell'esempio qui
Prima di scrivere il codice importiamo nella libreria un'immagine per la texture del cubo (wall.jpg
). Dalla libreria selezioniamo l'immagine e con il tasto destro del mouse e modifichiamone le proprietà. Spuntiamo Esporta in ActionScript e lasciamo che la classe wall.as sia generata automaticamente (click su OK alla pop-up di richiesta).
Infine inseriamo nello stage un MovieClip
che chiamiamo "mucca" su cui disegnamo delle palline grigie su fondo bianco e lo utilizziamo come texture per il cono.
È possibile scaricare il file sorgente .fla
Conclusioni
Anche se esistono molti sistemi per creare ombre più o meno realistiche, dobbiamo sempre ricordarci che Flash non è un motore 3D per cui i risultati per essere soddisfacenti devono tenere conto delle risorse limitate del player su cui gira l'applicazione che stiamo realizzando.