Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionLast revisionBoth sides next revision | ||
billboard [2020/01/10 11:31] – [Interact with grass shader] admin | billboard [2020/04/11 14:30] – [Billboard] admin | ||
---|---|---|---|
Line 4: | Line 4: | ||
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. | 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. | ||
+ | |||
+ | Restriction: | ||
We typically use this technique for grass or trees. | We typically use this technique for grass or trees. | ||
Line 54: | Line 56: | ||
FGrass := TGorillaBillboard.Create(FGorilla); | FGrass := TGorillaBillboard.Create(FGorilla); | ||
FGrass .Parent := FGorilla; | FGrass .Parent := FGorilla; | ||
- | FGrass.SourceObject := LBillboard; | + | FGrass.AddSourceObject(LBillboard); |
FGrass.MaterialSource := LGrassMat; | FGrass.MaterialSource := LGrassMat; | ||
FGrass.SetSize(GORILLA_BILLBOARD_SIZE, | FGrass.SetSize(GORILLA_BILLBOARD_SIZE, | ||
Line 110: | Line 112: | ||
===== Example: Terrain Grass Billboard ===== | ===== Example: Terrain Grass Billboard ===== | ||
+ | |||
+ | Since v0.8.1+ we've implemented a lot of new backend features (bounding volume hierarchy for TMeshDef, multiple billboard source objects, TGorillaModel support), which allows to multiple meshes and place those onto a terrain surface. | ||
+ | |||
+ | The following example will create 64 billboards, filled up with 64 copies of a grass template model. The billboards will be attached as childs to the terrain and rendered above. | ||
+ | All billboards will be placed as grid above the complete terrain. | ||
+ | |||
+ | __Notice:__ We could multiply the template model into a single billboard component, but the idea behind it, is to use the performance optimization of frustum culling. | ||
+ | By frustum culling only the visible billboard chunks will be rendered, therefore we can reduce vertex rendering a lot. | ||
+ | |||
+ | So at first we will load a grass template model. //Keep the mesh as simple as possible, because vertex count will increase fastly.// | ||
+ | |||
+ | To place a grass model copy in correct y-position on the terrain, we need to know vertices of the terrain. The new feature of bounding volume hierarchy (BVH) computation for TMeshDef' | ||
+ | |||
+ | For template model multiplication we use the new TGorillaBillboardTerrainFilling class, which automatically reads y-position from BVH. | ||
<file pascal> | <file pascal> | ||
+ | const | ||
+ | MAP_SIZE = 900; // terrain size (quadratic) | ||
+ | MAP_HEIGHT = MAP_SIZE / 4; | ||
+ | | ||
+ | var FGrassTemps : Array[0..0] of TGorillaModel; | ||
+ | |||
+ | procedure TForm1.CreateGrass(ATerrain : TGorillaTerrain; | ||
+ | const GORILLA_BILLBOARD_SIZE = 1; | ||
+ | GORILLA_MODEL_GRASS_1 = ' | ||
+ | |||
+ | var LTexPath | ||
+ | LGrass | ||
+ | LFillAlg | ||
+ | LChunks | ||
+ | LChunksPerRow : Integer; | ||
+ | i : Integer; | ||
+ | LChunkSize | ||
+ | LX, LZ : Single; | ||
+ | begin | ||
+ | if not Assigned(ATerrain) then | ||
+ | raise Exception.Create(' | ||
+ | |||
+ | // load the grass templates | ||
+ | LTexPath := IncludeTrailingPathDelimiter(AAssetsPath + ' | ||
+ | FGrassTemps[0] := TGorillaModel.LoadNewModelFromFile(FViewport, | ||
+ | LTexPath + GORILLA_MODEL_GRASS_1, | ||
+ | FGrassTemps[0].Visible := false; // it do not need to be shown | ||
+ | |||
+ | // create a list for all 64 billboard chunks | ||
+ | FGrassBillboards := TList< | ||
+ | |||
+ | // acquire a bounding volume hierarchy for much faster raytracing | ||
+ | // after usage, it will be destroyed, because it consumes a lot memory | ||
+ | // and we only need it for the moment | ||
+ | TMeshDef(ATerrain.Def).AcquireBVH(); | ||
+ | try | ||
+ | LChunks := 64; | ||
+ | LChunksPerRow := Ceil(Sqrt(LChunks)); | ||
+ | |||
+ | LChunkSize.X := (MAP_SIZE / LChunksPerRow); | ||
+ | LChunkSize.Y := MAP_HEIGHT; | ||
+ | LChunkSize.Z := (MAP_SIZE / LChunksPerRow); | ||
+ | |||
+ | for i := 0 to LChunks - 1 do | ||
+ | begin | ||
+ | // create multiple grass billboards to use frustum culling | ||
+ | LGrass := TGorillaBillboard.Create(FViewport); | ||
+ | LGrass.Parent := FViewport; | ||
+ | LGrass.Opaque := false; // allow translucent rendering | ||
+ | LGrass.TwoSide := true; | ||
+ | LGrass.Name := ' | ||
+ | |||
+ | // add the grass model as source object | ||
+ | // multiple source objects are possible and will be chosen randomly | ||
+ | LGrass.AddSourceObject(FGrassTemps[0]); | ||
+ | | ||
+ | // set the size of billboard chunk | ||
+ | LGrass.SetSize(LChunkSize.X, | ||
+ | |||
+ | LX := -(MAP_SIZE / 2) + ((i mod LChunksPerRow) * LChunkSize.X); | ||
+ | LZ := (MAP_SIZE / 2) - (Floor(i / LChunksPerRow) * LChunkSize.Z); | ||
+ | |||
+ | // place billboard chunk over terrain | ||
+ | LGrass.Position.Point := Point3D(LX, 0, LZ); | ||
+ | | ||
+ | // take the template model material source as material for the billboard | ||
+ | // this could be replaced by a grass material shader of course | ||
+ | LGrass.MaterialSource := FGrassTemps[0].Meshes[0].MaterialSource; | ||
+ | FGrassBillboards.Add(LGrass); | ||
+ | |||
+ | // fill up billboard chunk with 64 copies of our grass template | ||
+ | LFillAlg := TGorillaBillboardTerrainFilling.Create(LGrass, | ||
+ | try | ||
+ | LFillAlg.Count := 64; | ||
+ | LGrass.Fill(LFillAlg, | ||
+ | finally | ||
+ | FreeAndNil(LFillAlg); | ||
+ | end; | ||
+ | |||
+ | // we put grass billboard into terrain model | ||
+ | LGrass.Parent := ATerrain; | ||
+ | end; | ||
+ | finally | ||
+ | // at the end we destroy the bounding volume hierarchy again to free memory | ||
+ | TMeshDef(ATerrain.Def).ReleaseBVH(); | ||
+ | end; | ||
+ | end; | ||
</ | </ | ||
Next step: [[inventory|Inventory]] | Next step: [[inventory|Inventory]] |