Many small objects optimisation

From JReality Wiki
Jump to: navigation, search

- see also More than 1000 geometries


openGL 3 has a serious drawback when rendering many small objects. In fixed function openGL <2 display lists could be called quickly, whereas in openGL 3 they are not available and setting up all buffer bindings makes performance issues, when rendering many small vertex buffer objects.


Therefore the openGL 3 backend needed either "bindless graphics" which is only available on nVidia GPUs or a framework that avoids vertex buffer object bindings. The latter has been implemented as follows in the class jogl3.optimization.RenderableUnitCollection for geometries with neither edge drawing nor vertex drawing nor transparency:


  • IndexedFaceSets with the same Texture, Shader and Reflection Map are grouped into so called "RenderableUnits".
  • Inside the RenderableUnits the Geometries are divided into groups of at most 16 000 geometries, these Groups are called "InstanceCollections".
  • The InstanceCollections contain up to 16 000 "Instances". Each Instance contains a Geometry, the corresponding Appearance state and a transformation matrix.
  • An InstanceCollection merges all the vertex buffer objects of its Instances into one "big vertex buffer object" (BVBO) for each type of shader "in" attribute. Furthermore all the Appearance data are written into a single texture (instead of being passed as glUniforms), one line per Geometry, i.e. up to 16 000. The transformation matrices are also written into this texture (instead of being passed as glUniforms).
  • The addition and removal of a Geometry into an InstanceCollection causes in most cases only constant time. This is due to the fact, that the size of the BVBO is chosen as power of two, and contains therefore available space at the end. However when too much space is free, then the BVBO will be defragmented or resized automatically.
  • An InstanceCollection contains one additional BVBO storing the index of the Geometry at that position, i.e. the line in the texture containing the uniform variables.
  • At the end also the GLSL shader has to be rewritten, this is done automatically as well. All uniforms are replaced by one texture sampler, and the variables are retrieved as TexelFetches.


The variable

 
jogl3.optimization.RenderableUnitCollection.MAX_NUM_FLOATS

defines the maximum size of a Geometry to be passed to the optimization process.


The variable

 
jogl3.optimization.InstanceCollection.MAX_NUMBER_OBJ_IN_COLLECTION

must be below the maximum texture dimension (usually 16 000). defines the maximum size of a Geometry to be passed to the optimization process.


TODO: currently the InstanceCollections and RenderableUnits that have become empty are not cleaned up. This can cause problems, when changing textures, shaders or reflection maps often during an application run.