3D Engine


Context

First time in contact with a 3D Engine code. Pretty intensive work and a lot of code rewritten during the last year on ESAT. This engine has been the result of the work with Imanol Saenz Aguirre.

Demos

Xavier Rebasa Moll

Imanol Saenz Aguirre

Apis Used

  • OpenGL + GLFW
  • ImGui
  • Bullet

Main Features

Project

Structure

User-Engine Comunication

The engine code has been implemented in a way that a user can manipulate the data without using any core class. The user changes are applied before rendering but not at the moment the user requested.

//User Code

Node n; //Invalid identifier, any change won't be applied
n.Create(); //Insertion to the engine node system, ID is now valid

while (!engine.IsClosed()) {
	//Change node
	engine.EndFrame();//Changes are applied
}

Instancing

Any node can be set as an instance node. When this happens that node will be added to an array of objects that share the same properties, based on material and geometry used.

That structure uses a node as a shared parent for all the instances nodes of the list. That way, only one world matrix needs to be calculated and all the information sent to the GPU is relative to that parent.

image-center

Rendering

Forward Rendering

Each object/structure to be rendered is added to a vector being processed at the engine thread when ready.

Oclussion Culling

Each object/structure handles an OpenGL query. That query is configured to return true if any pixel has been rendered for that object. In the case of an instanced, object it returns true if any of the nodes in the structure has been able to render any pixel.

image-center image-center

//After a simple render (just bounding boxes with no texture)
DisplayList dList;
for(NodeCore& node : engine.nodeSystem_.activeNodes_){
	node.query_.GetResult() ? dList.push_back(node);
}
for(NodeCore& node : dList.list){
	node.Draw();
}

Lightning

This engine is able to handle 64 point lights, 32 spotlights and 8 directional lights although only directional lights cast shadows. Each directional light saves a depth 2DTexture which is sent to the render shader to render the shadows.

image-center

Physically Based Rendering (PBR)

Each node has a list of available materials to be applied. That material will handle all the textures needed for PBR to work. [Albedo, NormalMap, Metallic, Roughness, AmbientOclussion]. That allows rendering an object more realistically as its physical properties are taken into account when rendered.

  const char8* a =  "../data/textures/rustediron_albedo.png";
  const char8* n =  "../data/textures/rustediron_normal.png";
  const char8* m =  "../data/textures/rustediron_metallic.png";
  const char8* ro = "../data/textures/rustediron_roughness.png";
  const char8* ao = "../data/textures/rustediron_ao.png";

Material mat;
  mat.SetDisplayName("Material 1");
  mat.SetTexture(TextureType::kTT_Albedo, a);
  mat.SetTexture(TextureType::kTT_Normal, n);
  mat.SetTexture(TextureType::kTT_Metallic, m);
  mat.SetTexture(TextureType::kTT_Roughness, ro);
  mat.SetTexture(TextureType::kTT_AmbientOclusion, ao);

Physics

Bullet

Bullet physics library has been implemented and used to handle nodes with gravity and collisions enabled.

Updated: