This is an old revision of the document!
Billboard
A billboard controls proxy objects of a basis mesh instance (source object).
The billboard component is a mesh itself, into which proxies are merged. Much faster rendering is possible if proxy meshes are merge into one mesh, instead of rendering each mesh.
We typically use this technique for grass or trees. It is not suitable for animated meshes.
Using a grass billboard
In this example we will display grass on multiplied planes inside of the billboard component. After applying the TGorillaGrassMaterial we are able to render different textures onto those planes and to manipulate vertices.
The result should be a varying grass landscape with waving grass.
- Form1.pas
procedure TForm1.FormCreate(Sender: TObject); var LBillboard : TPlane; LPoolE : TGorillaBitmapPoolEntry; LGrassMat : TGorillaGrassMaterialSource; LAlg : TGorillaBillboardRectFilling; begin // creating the source object - here a plane LBillboard := TPlane.Create(fGorilla); LBillboard.Scale.Point := Point3D(4, 4, 4); // creating the grass material source FGrassMat := TGorillaGrassMaterialSource.Create(FGorilla); FGrassMat.Parent := FGorilla; // now we load a pool of grass textures, the material shader // randomly chooses from with FGrassMat do begin LPoolE := Bitmaps.Add() as TGorillaBitmapPoolEntry; LPoolE.Bitmap.LoadFromFile('grass1.png'); LPoolE := Bitmaps.Add() as TGorillaBitmapPoolEntry; LPoolE.Bitmap.LoadFromFile('grass2.png'); LPoolE := Bitmaps.Add() as TGorillaBitmapPoolEntry; LPoolE.Bitmap.LoadFromFile('grass3.png'); LPoolE := Bitmaps.Add() as TGorillaBitmapPoolEntry; LPoolE.Bitmap.LoadFromFile('grass4.png'); end; // creating the billboard control FGrass := TGorillaBillboard.Create(FGorilla); FGrass .Parent := FGorilla; FGrass.SourceObject := LBillboard; FGrass.MaterialSource := LGrassMat; FGrass.SetSize(GORILLA_BILLBOARD_SIZE, GORILLA_BILLBOARD_SIZE, GORILLA_BILLBOARD_SIZE); // create an individual filling algorithm to multiply the grass planes LAlg := TGorillaBillboardRectFilling.Create(FGrass); try FGrass.Fill(LAlg, true); finally FreeAndNil(LAlg); end;
Interact with grass shader
The default grass shader provides functionality to bend the grass planes at a certain point. To enable interaction, f.e. at mouse position, we can simply configure the TGorillaGrassMaterialSource:
- Form1.pas
FGrassMat.SpotRadius := 0.5; FGrassMat.SpotEnabled := true;
And in the OnMouseMove event we can set the current interaction point like this:
- Form1.pas
procedure TForm1.DoOnViewportMouseMove(ASender : TObject; AShiftState : TShiftState; X, Y : Single); var LPt3D : TPoint3D; LRayPos, LRayDir : TVector3D; begin if FMove then begin if (ssLeft in AShiftState) then begin FGorilla.BeginUpdate(); try LPt3D := FGorilla.ScreenToWorld(PointF(X, Y)); FGorilla.Context.Pick(X, Y, TProjection.Camera, LRayPos, LRayDir); FGrass.RayCastIntersect(LRayPos, LRayDir, LPt3D); // apply scaled light position FGrassMat.Spot := TPoint3D(LPt3D); finally FGorilla.EndUpdate(); end; end; FLatest := PointF(X, Y); end; end;
Next step: Inventory