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
- Structure
- Rendering
- Physics
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.
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.
//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.
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.