Blacksite: Deep Horizon

Blacksite: Deep Horizon is a first person wave defence game inspired by Titanfall Frontier Defense. Made in our engine, Dream Engine.

Itch: Blacksite: Deep Horizon

Details
  • Genre: FPS, wave defence
  • Engine: Dream Engine
  • Duration: 16 weeks at 50%
  • Team: 6 programmers, 4 artists, 2 level design, 2 procedural artists
My contributions for this project:
  • Shader import tool
  • Instanced models
  • Post processing
  • Particle system

Shader import tool

I created a shader import tool to make the pipeline easier for our procedural artists to create pixel shaders using Visual Studio's shader graph editor. The graph editor is called Shader Designer. The tool was really helpful in implementing the shaders into our engine. 

I decided to rewrite our structure for our previous buffers send to the GPU to be offset by the amount used by shader designer to allow for easy implementation without having the requirement to edit the .hlsl file exported by Shader Designer. This took some time to figure out and make it work as intended without breaking any previous functionality of our code. 

One of the shaders imported using the tool.

I have a full page dedicated to the Shader Importer tool. If you wish to read more about it press the link below.
Shader Importer

Instanced models

To help with performance I changed our model loading and rendering to using a instanced system. When using instanced models only one unique model is loaded and all objects using that exact model draws from the same model. Instead of each object having its own model. 

The code below loads the models on a separate thread when the game starts. This is started in the splash screen to load the levels as fast as possible when the splash screen is finished. 

const std::string modelPath(aLevelData.fbxPaths[someUntaggedID[i]].begin(), aLevelData.fbxPaths[someUntaggedID[i]].end());

auto it = aInstancersMap->find(modelPath);

if (it == aInstancersMap->end()) 
{
    DE::ModelInstancer inst;
    std::wstring path = L"../Assets/";
    if (modelPath.size() > 0)
    {
        path += std::wstring(modelPath.begin(), modelPath.end());
    }
    else
    {
        path = L"D:\Perforce P7\DreamEngine\Assets\3D\cubePrimitive.fbx";  //Failsafe if model was not found.
    }

    std::shared_ptr<DE::Model> mdl = CustomLoad::LoadModel(path).GetModel();
    inst.Init(mdl);
    path = std::wstring(path.begin(), path.end() - 4);
    CustomLoad::AssignMaterials(path, mdl, inst);
    aInstancersMap->insert(std::make_pair(modelPath, inst));

    loadingModelMutex.lock();
    someModelInstancers->push_back(&aInstancersMap->at(modelPath));
    loadingModelMutex.unlock();
}

After all the models are loaded only the transform of each model are pushed into the  vector of models. As the code below shows.

for (int i = 0; i < someUntaggedID.size(); i++)
{
    const std::string modelPath(aLevelData.fbxPaths[someUntaggedID[i]].begin(), aLevelData.fbxPaths[someUntaggedID[i]].end());
    auto it = aInstancersMap->find(modelPath);
    it->second.AddInstance(aLevelData.transforms[someUntaggedID[i]]);
}

This setup of pre loading the models on a separate thread and then only pushing the transforms when loading a level reduced our loading time from about 16 seconds to around 1 second when loading the same level. 

Loading time after model instancing was finished

Post processing

Using the shader importer tool I created, I added an on screen function to render a shader on the screen instead of on a model in the world. Adding the on screen effects gives a great feeling of what is happening in the game while playing.

One of the earliest VFX in our game and engine
Damage effect
Healing effect

Particle system

The particle system used in this game project is something I have developed during my time at The Game Assembly and the tool is something I am very proud of. The tool has been implemented and used in every game project I have done since the creation of the tool (4 game projects). 

The tool started out as a 2D particle system only but has since had a few upgrades. If you wish to read more about the particle system please click the link below.
Particle System