Il billboarding è una tecnica molto vecchia per ingannare l'occhio dello spettatore facendogli sembrare delle semplici immagini 2D delle immagini 3D inserite nella scena. Ad esempio se abbiamo necessità di aggiungere molti alberi alla nostra scena: se l'albero è molto complicato sarà formato da un certo numero di poligoni che moltiplicati per tutti gli alberi renderebbe difficile il lavoro del PC. In questo caso noi possiamo utilizzare semplicemente una foto di un albero ed attaccarla ad un rettangolo. Se non abbiamo necessità di avvicinarci troppo (ad esempio degli alberi in una zona distante) il risultato sarà molto elevato e le richieste hardware minime. Creare un rettangolo con coordinate texture non dovrebbe essere difficile, i problemi sono essenzialmente 2: fare in modo che si veda solo l'albero e non lo sfondo della texture (alphablending) e soprattutto fare in modo che da qualsiasi posizione noi guardiamo il rettangolo questo sia rivolto sempre verso di noi.
Per il primo problema esistono infinite soluzioni, io propongo quella della maschera. Prendete la foto del nostro albero ed una maschera come quella che vedete:
Caricherete la prima nel primo indice mentre la seconda nel secondo. La prima dovrà avere il colorKey impostato a nero( D3DColorMake(0,0,0,1) ). Settate il device come segue:
device.RenderState.AlphaBlendEnable = True
device.RenderState.SourceBlend = Blend.SourceAlpha
device.RenderState.DestinationBlend = Blend.InvSourceAlpha
device.TextureState(1).ColorOperation = TextureOperation.Modulate
device.TextureState(1).ColorArgument1 = TextureArgument.TextureColor
device.TextureState(1).ColorArgument2 = TextureArgument.Current
device.SetTexture(1, t1)
device.SetTexture(0, t2)
device.TextureState(1).TextureCoordinateIndex = 0
Ora renderizzate il rettangolo con le coordinate texture adatte e la zona viola sparirà e rimettete a posto il device
device.RenderState.AlphaBlendEnable = False
device.TextureState(1).ColorOperation = TextureOperation.Disable
Ricordate di porre a nothing la seconda texture. Questa è solo una configurazione, ne esistono altre. Ora il problema dell'orientamento viene risolto semplicemente calcolando l'angolo tra la telecamera e l'oggetto. Per chi non riesce ecco la funzione
Function getAngolo(ByVal o As Vector3, ByVal c As Vector3) As Single
Dim ax As Single
Dim ay As Single
ax = c.X - o.X
ay = c.Z - o.Z
If ay < 0 Then
getAngolo = Math.Atan(ax / ay) / rad + 180
End If
If ay > 0 Then
If ax > 0 Then
getAngolo = Math.Atan(ax / ay) / rad
Else
getAngolo = 360 + Math.Atan(ax / ay) / rad
End If
End If
If ay = 0 Then
If ax > 0 Then getAngolo = 0 Else getAngolo = 180
End If
End Function
muoviObj SX, SY, SZ, 0, angoloRestituito + 180, 0, PX, PY, PZ
Dove o è la posizione dell'oggetto e c quella della telecamera(il primo vettore quando si crea la matrice). L'angolo ricevuto è l'angolo Y che deve avere un rettangolo disposto sul piano XY. La posizione dell'oggetto dovrà naturalmente essere quella specificata. Questo algoritmo funziona solo con una telecamera impostata con l'asse Y verso l'alto, per altri orientamenti dell'asse basta cambiare X o Y con Z a seconda. Inoltre l'algoritmo mantiene comunque l'oggetto verticale (ruota solo sull'asse Y). La tecnica risulta ottima per tutti gli oggetti che non richiedono una vera realizzazione 3D ma con un pò di astuzia possono essere fondamentali per alcuni effetti (fuoco, pioggia, neve, lens flare etc) . Alcuni vecchi giochi hanno utilizzato questa tecnica per i famosi giochi in mode7 (i primi doom ad esempio) e ancora oggi è utilizzato continuamente come alternativa ai sistemi particellari (inutili se ogni particella è diversa dalle altre). Ultima nota fondamentale: ricordate l'alphablending? Solo se un oggetto viene renderizzato dopo quello dietro risulta trasparente. Di conseguenza ordinate sempre gli oggetti renderizzandoli dal più lontano al più vicino.
Esempio VB.Net