This Engine is done as part of the content of the Master in Advanced Programming for AAA Videogames. With a team of 22 people, 5 artists and 17 programmers, it is a one year project that consists on building an Engine from scratch and after it, creating our own video game using the engine created. This post is dedicated to show the work done in terms of Engine Programming.
Some of the features that Tesseract has are:
- 3D Scene editor with Unity-like controls
- PBR rendering pipeline
- Particles
- Animations
- Responsive 2D UI module
- C++ Scripting support
- Recast/Detour navigation
- Bullet physics
- 3D sound
I was in charge of three different modules:
- Graphics Module
- Particle System
- Audio Module
Graphics Programmer
PBR Phong Model
As a graphics programmer, I started developing the the PBR Phong model. This model is a Physically Based Rendering (PBR) model using Bidirectional Scattering Distribution Functions (BRDF). In our case, we use Bidirectional Reflectance Distribution Functions (BRDF) functions, ignoring the Transmittance part of BSDF. This model takes into account the light to calculate the reflections to the surfaces of the model. This model includes shininess value, diffuse and specular textures.
We also add the Fresnel effect to the Phong equation to gain more realistic reflections depending on the light incoming angle. The different types of light we support are:
- Directional light
- Point light
- Spot light
Cook-Torrance Reflectance Model & Normal Mapping
After that, we imporve the model using Cook-Torrance BRDF and Fresnel equations. It is an extension from Normalised Phong BRDF. It allows adding more information to textures like specular with metallic values achieving more realistic materials. After that, we added the Normal Mapping with the Normal Map texture. It allows the artists to create more realistic models with more sense of volume.
Alpha Blending
When we started to put materials that needed some transparency, we realized that we only supported opaque materials. For different models like doors or trees, it’s necessary to take into account the alpha channel from the textures. Moreover, it’s necessary to draw them in a specific order. Otherwise, the GPU can print them in the order it wants and some transparencies won’t be applied. I implemented the changes in the shader code to take the alpha channel, but also an algorithm to order the objects in the camera direction. This way, we print firstly the opaque materials and then, the transparent ones.
Particle System
For the Particle System, I worked on the base structure done by my team mate Telm Serra adding all the features that our VFX team requested. Now, all these features will be explained with some examples:
- Basic parameters
- Basic options of the PS like the duration of the emitter and start parameters of each particle. Also the maximum number of alive particles and some control variables like loop or reverse effect.
- Emission parameters
- Particles are attached to emission movement and rotations, or particles behave independently where there are emitted, without any change when the emitter is modified. We can also control their spawn rate.
- Gravity
- An implementation of the Parabolic motion formulas. You can control the gravity in the Y-axis direction.
- Shape (Cone, Sphere, Circle, Box)
- Each shape has internal parameters like radius, radius thickness and arc of emission. The box has different options of emission: from inside the volume, from edges, and from the shell. All of them have an internal local model to modify the local position inside the game object.
- Overlifetime modifications (Velocity, Rotation, Size and Color)
- For the velocity, the three axes are separated to have independent values depending on the direction we want to modify. It also has a speed modifier that modifies the start speed of the particle, and a space-related option to change between Local and World.
- For the color, we add an extension of the Imgui library. It is a gradient color script developed by David Gallardo that allows you to change the four parameters of the color (RGBA) in a gradient way.
- Flipbooks
- It allows having an animated flipbook with different tiles. You can modify the animation speed, among others.
- Render module
- It section controls the alignment of the texture, also all the related texture settings. For the billboard model, we have Billboard, Stretched Billboard, Horizontal Billboard, and Vertical Billboard. For the normal Billboard mode, the Render Alignment options are: View, World, Local, Facing, and Velocity.
- We have also two types of render: additive for black backgrounds and transparent to take the alpha channel of the texture.
- With the texture, you can modify the intensity of each channel color (RGB), flip it and apply some softness for effects like smoke.
- Collisions
- Trails
- Sub Emitters
- We can instantiate temporal new particle systems for each particle depending on the status we set. It can be by particle birth, death, or collision. This sub emitter is deleted when it has finished emitting to avoid having inactive sub emitters in the hierarchy of the scene. This process is recursive.
- Lights
- For the lights, they work similarly to the sub emitters. A copy of a reference light is instantiated and deleted with the particle. It has different parameters like intensity, the ratio of emission, also different parameters for the color. There is also a security parameter for the maximum lights to avoid overcharging the render pipeline. Finally, you can change the local position of the light related to the particle.
- Randomness & behaviour curves
- We have implemented a similar system Unity has for randomness. For each parameter, you can choose between a constant value or a random value between two constants. Moreover, to add more realistic behaviors to different effects, we have implemented a curve module that depending on the lifetime of the particle, you can set different values. There are different curve models like quadratic, cubic, exponential, among others. We used an extension of Imgui from Gavin Ray.
- Component Billboard (independent from PS)
- Taking the first approach that Telm Serra did, I’ve adapted the Component Billboard with some features from Particle Systems. It includes adding gradient color and doing a small refactor about how the lifetime is controlled inside the component.
All of these features have different parameters. You can control them via a Component or from the scripting module that the Engine has. Here you can see how the component looks like:
And finally, a visual demo with examples from the different features the particle system has:
Audio Module
For the Audio Module, we integrated OpenAL library. All the Audio Module consists on:
- OpenAL Library
- Integration of the basic functionalities of the library. Creation of a Module Audio inside the Engine to manage the library.
- Component Audio Listener
- Component from the Engine where we set the position and configuration of the listener of the game. It includes parameters like model distance and Doppler factor.
- Component Audio Source
- Component from the Engine where we set the position and configuration of the emitter source. It includes parameters like gain, pitch, loop, and 3D position values like the type of source (omnidirectional or directional), reference distance, roll-off factor, with the possibility to set the source in 2D or 3D mode.
- Audio Importer
- Creation of the audio resource and the importer options for the original file. You can convert it to mono or change the compression format between PCM (.wav) or Vorbis (.ogg).
- Output device
- List all the audio devices from the computer to be able to change it from the Engine.
- Audio Channels
- Implementation of different audio channels to separate the assets that are music from the ones that are SFX. It allows you to manage different gains for different channels.
General Tasks
- Bounding Boxes & Frustum Culling
- We added bounding boxes for each of the imported models. It allows us to use them for some techniques as Quad-tree, Frustum Culling, or Ray Tracing, among others.
- With the bounding boxes, we can implement a Frustum Culling technique. It allows us to discard the models that aren’t inside the Frustum of the camera. This way, we don’t need to draw it, since they won’t be visible when the user is viewing the scene. It allows us to optimize the render module of the Engine.
- Ray Tracing & Gizmo
We developed a way to be able to select a model from the scene to modify it directly with the Gizmo. We use a Ray Tracing technique for this purpose. It consists of a ray that is cast from a position of the screen. It is converted to world coordinates from what the Frustum is facing. It goes across all the bounding boxes that is crossing to discard objects that are not in the trace. When there is a match with any bounding box, it search if it is colliding with any of the faces of the model and it takes the model that es nearer to the camera.
For the Gizmos, we use a Library that can be integrated to our UI Library ImGui. It is called ImGuizmo. It consists on a Gizmo that allows us to translate, rotate and scale the model. It also contains a box gizmo to change the plane view of the scene.
You can check it in our GitHub page: Tesseract repository