Rendering

In Forge of Empires

Problems

  • Flash
  • OpenFL
  • WebGL

Trick 1: SubBitmapData

  • extends BitmapData
  • references a texture region
  • doesn't "cut-out" a new texture

Trick 2: Batching

... is problematic

Problem 1

No batching in OpenFL

 ¯\_(ツ)_/¯

Problem 2

Naive batching is useless

Solution

Multi-texture batching

Usual drawing

  • Bind some texture
  • Upload vertex positions and texture coordinates

  • Draw vertices with that texture using a shader

Multi-texture drawing

  • Bind as many textures as the video card supports
  • In addition to position and texture coordinates, add texture id to the vertex data
  • Draw vertices with all these textures at once with a bit more complex shader

OpenFL/WebGL

  • Every renderable object is just like a Bitmap in the end
  • We replace the bitmap render method to add the object into the batch instead of rendering it
  • After the stage is traversed, flush whatever remains in the batcher

Batching algorhithm

  • On stage traversal:
    • Collect rendered objects (quads)
  • On flush:
    • Prepare vertex data for the collected quads
    • Also group them into "render groups", each of which define a single draw call:
      • slice of vertex data to draw
      • multiple textures to bind
    • Upload vertex data
    • Iterate over render groups and do actual drawing
      • Bind group's textures
      • Draw the corresponding slice of vertices

Benefits

  • Forge of Empires UI consists of hundreds of Flash display objects

  • ...but we use texture atlases and that SubBitmapData trick, so not that much textures on the GPU...

  • With up to 16 textures batched together, instead of doing 300 draw calls we do just 15 of them, hitting 60fps on a shitty laptop in MS Edge

  • All without reworking the actual game code or assets \o/ 

Further thoughts

  • Instanced rendering?

Made with Slides.com