Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

Qt3D Renderer Scene Update Strategy

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Qt3D-wip-newapi-Overview

Qt3D Renderer Scene Update Strategy

Backend Rendering classes

A Backend SceneGraph tree is built from the Frontend SceneGraph Tree. This allows to monitor the Frontend SceneGraph tree nodes for updates, perform computations in parallel and contiguously order resources in memory.

* RenderNode

Maps to : Entity

* RenderCamera

Maps to Component : CameraLens

* MeshData

Maps to Component: Mesh

* RenderMaterial

Maps to Component: Material

* RenderTechnique

Maps to Node : Technique

* RenderShader

Maps to Node : ShaderProgram

RenderSceneBuilder

Builds a tree of backend entities from the root of the frontend SceneGraph tree. Recursively traverses the SceneGraph tree. For each Entity traversed, a RenderNode is created. Each entity has a unique id which allows us to retrieve the backend element from a frontend one.

Foreach of the following contained component properties :

  • Material -> creates a RenderMaterial
  • CameraLens-> creates a RenderCamera
  • Mesh -> creates a MeshData
  • Transform-> sets the RenderNode localTransform matrix to transform
  • FrameGraph -> sets the builds and sets FrameGraphNode tree

Things that should change :

  • Check wether RenderEffect and RenderRenderPass classes are needed
  • QChangeArbiter should monitor updates Transforms, Materials, CameraLens …
  • Have lazy loading of backend entities

RenderView and RenderCommands

Once the SceneGraph and FrameGraph trees have been populated, the actual rendering can take place.

Before the scene can be rendered, a few computations have to be performed. Those include :

  • Word transform
  • Bounding volume
  • Camera scene culling
  • Loading meshes that haven' t been loaded yet
  • Creating a set of rendering command based on the FrameGraph's description

Those computations can easily be performed in parallel and that's where the thread pool and the jobs come in handy.

A few classes act as wrappers around these jobs

  1. LoadMeshDataJobs-> one instance per mesh to load
  2. UpdateWorldTransform -> one instance in total
  3. UpdateBoudingVolumJob-> one instance in total
  4. RenderViewJob -> one instance per leaf node of the FrameGraphTree

Each job batch is executed in the order defined above and is dependent on the completion of the batch launched prior to it.

Note: As these jobs are executed in a thread context that is not the same as the thread owning the QOpenGLContext, none of these jobs can actually perform OpenGL draw calls or OpenGL VAO/VBO initialization / filling.

A RenderView instance is created for each FrameGraph leaf node. It contains :

  • Handle to a RenderCamera
  • Viewport rectangle
  • TechniqueFilter
  • RenderPassFilter
  • An array of RenderCommand

The RenderCommand class actually contains low level data :

  • OpenGLVertexArrayObject
  • QMatrix4x4-> world transform matrix
  • QOpenGLShaderProgram
  • QUniformPack -> uniform names and values to be bound to the shader
  • MeshData-> Mesh data on the CPU side memory
  • Handle to a RenderMaterial

Note: This is a temporary description that should evolve quite a bit in the following weeks as we figure out what works, what doesn't, what's missing …

A RenderView is filled in a two step process.

  1. The Backend FrameGraph tree is traversed from the leaf node to the root. This allows to retrieve the camera, viewport, technique and renderpass filters.
  2. The Backend SceneGraph tree is culled and RenderCommand are built

The Backend SceneGraph tree is recursively traversed. For each RenderNode:

  • If there is a MeshData indexed using the same Entity Uuid as the current RenderNode

' Set the RenderCommand's MeshData to of the MeshData ' Set the RenderCommand's matrix to the RenderNode's worldTransformMatrix ' Set the Material handle to to the handle indexed by the Entity Uuid

Each RenderView object once filled is inserted in order in a temporary queue owned by a QCircularBuffer. When the number of required RenderView instances for a frame is reached, this process is repeated with a new empty queue.

What should change

  • Once a MeshData has been uploaded to the VAO/VBO once, this could be freed and removed from a RenderCommand.
  • Have a way to store VAO/VBO pointer
  • See what has to be done improved so that memory reordering doesn't affect the process of building the RenderCommand objects