Skip to main content

Organizing the Scene Tree

One of the core objectives of a 3D rendering engine is to organize a well-structured and efficient scene tree. The scene tree is a hierarchical structure used in rendering engines to organize and manage all objects in a scene. It is typically represented as a tree-like data structure composed of a series of rendering nodes, where each node can contain child nodes, forming the common parent-child relationship structure found in 3D models.

In this section, we will explore:

  • Organization of the Scene Tree
  • Render Passes
  • Render Nodes
  • Primitives
  • Context Management
  • Rendering Pipeline

Scene Tree Organization

Below is an example of a typical scene tree in ORE. A scene tree has multiple levels of organization. At the root is the rendering scene (scene), which can contain multiple rendering passes (renderPass). Each render pass can be understood as a separate rendering layer, with each layer managing its own rendering objects.


Render Passes

A render pass is essentially a logical organizational concept that helps the rendering engine manage the scene in layers. Imagine a painting composed of multiple layers: the first layer is the distant clouds, the second layer is the mountains in the background, and the final layer is the nearby rivers and trees. Similarly, we use render passes to divide objects in the scene into different layers based on certain rules (e.g., purpose, type, or rendering order). This separation of rendering logic allows the engine to respond more efficiently to changes in the scene.

Each render pass can be rendered independently and is often used to handle different types of objects, such as backgrounds, normal geometry, or highlighted geometry for selection.

A render pass includes its own rendering background (background), camera (camera), and render nodes (node). Render nodes represent the objects to be rendered, while the camera determines the viewing perspective of the objects.


Render Nodes

Render nodes represent the actual objects to be rendered in the engine. They include 3D mesh data (mesh), material (material), geometry (geometry), and transformation information (transform). Since industrial models often have multi-level parent-child structures, render nodes generally also contain a series of child render nodes (children:[]).

The mesh is composed of a series of primitives, which we will discuss next.


Primitives

In industrial design, various modeling software can be used to create a wide variety of 3D models. The basic elements that make up these models—such as vertices, control points, lines, or faces—have precise mathematical representations. Regardless of the type of curve or surface, when discretized, they can form unified primitives, which serve as the raw materials for the rendering engine. Primitives typically include the following:

  • Vertex Data: Defines the shape of the model, including position, normals, and texture coordinates.
  • Index Data: Defines how vertices are connected to form the triangular faces of the model.
  • Appearance Attributes: Defines the color, texture, glossiness, etc., of the model.
  • Textures: Mapping data used to enhance the details of the model.

Primitives are essentially an abstraction and encapsulation of low-level graphics APIs. They include both geometry (geometry) and material (material). At the end of the scene tree, there is a large amount of geometric data and material properties. Geometry describes what the rendering object is, typically expressed using vertex buffers (VBOs) and index buffers (IBOs). Material properties describe how to render these objects, using programmable vertex/fragment shaders (Program), parameters (Parameter), and states (State). These topics will be covered in detail in subsequent tutorials.

If a primitive does not define a material, it can inherit the material defined in its parent render node. The same applies to geometry. This means that all primitives can share the same material or geometry if needed.


Rendering Context Management

(Details about rendering context management can be added here, depending on the specific implementation in ORE.)


Rendering Pipeline

The rendering pipeline is the core workflow of a rasterization-based rendering engine. Its function is to use the rendering elements contained in a rendering context to produce 2D images on the screen. Here, we will briefly introduce the inner workings of the rendering pipeline and explore the key stages that transform raw data into visually compelling effects on the screen.

Data Preparation: 3D Models

Before entering the rendering pipeline, a series of 3D rendering units have already been organized through the scene tree. The rendering pipeline uses the geometric data (vertex information in VBOs and index information in IBOs) and material properties from these rendering units as input.


Vertex Processing: Shaping the Scene

At this stage, the raw vertex data from the model is transformed into a format suitable for the GPU. The vertex processor, or vertex shader, applies camera transformations to these vertices, performing operations like scaling, rotation, and translation to position the model within the camera's view. Additionally, culling calculations are performed to remove vertices that fall outside the camera's view.


Rasterization: From Polygons to Pixels

Before rasterization, there is a hidden step called primitive assembly, which connects adjacent vertices into triangles. At this stage, the data is still 3D. Rasterization projects these geometric triangles onto the screen, forming pixel regions in a 2D screen coordinate system. After rasterization, each pixel generates a fragment, which is a collection of states such as screen coordinates, depth information, normals, and texture coordinates. These states are used to calculate the final color of each pixel.


Fragment Processing: Drawing Pixels

At this stage, each fragment (individual pixel) on the screen is processed to bring textures and material properties to life. The fragment shader determines the final color of each pixel based on the texture and material properties associated with the corresponding vertices. After determining the color information for each fragment, additional per-fragment processing is performed, such as depth testing (to determine which fragments are closer to the camera) and blending (to make objects appear transparent).


Framebuffer: Displaying the Final Image

The final rendered image, composed of individual pixels, is stored in a memory buffer on the graphics card called the framebuffer. The browser then retrieves this data and displays it on the screen, bringing your 3D models to life on the webpage.

By understanding the 3D rendering pipeline, we can gain deeper insights into how a rendering engine transforms raw data into advanced shading and lighting effects, creating visually compelling results.