VEngine 0.2

General improvements of the code base and extension of features

VEngine_cover

This framework is a static library and project. Capable of rendering PBR materials in both forwards and deferred models.

It uses Directx11 for the rendering (with effects11), a custom made obj parser to read meshes and a DDStexture loader for simple textures.

You as the user can adjust settings and play around with the scene using the simple but effective ImGUI UI. Which updates everything in realtime.

Framework

In the previous version page of this framework I talked about how I wanted to expand upon its capabilities. And I think I achieved a large part of that, by focussing on some core problems in the piping of the renderers as well as how data gets handled. While constantly keeping in mind if I am making the API easier or more difficult to use. Which I think is the most difficult part in this since you can easily make loads of features. But then later down the line you would end up realising that you can no longer move forwards with what you have done, forcing you to refactor.

I think now the "engine" is in a decent spot, that allows me to move forwards with more user interaction. Things like input for keyboard, mouse, perhaps even gamepads? Or adding object selections, gismos for editing the world. More graphical features in postprocessing, volumetrics, skeletals, etc.

Features

I have added some new features besides solidifying the backend.

New features:

  • Logging system

  • Postprocess pipeline

  • Full screen copy pass

  • Greyscale postprocess

  • Graphics debug annotations

  • Shader environmental pragmas

  • Per Object metal/rougness

normalscombinedvsperpoly

A note related to the new features:

Postprocessing is one of the most powerful and important steps in any graphics pipeline as such I have added it in an expandable as possible form. Besides the structure I also made a full screen copy shader, this will facilitate the addition of techniques that require either require duplicates for temporal use or otherwise. To start however, I made a simple greyscale to test functionality of the systems.

With all the new complexity being added to the pipeline I made it a priority to have more visibility on what is happening in the framework. For that one of the simplest and most effective things to do is adding a logger. Besides that I also added render annotations, this way debugging via Renderdoc or Nvidea Insights will become much easier.

Also with my expansion of mesh functionality the generation of normals and acceptance of uv-less geometry I had to think of expanding material capabilities. My "ubershader" can now handle per object metalness, roughness and albedo. All of this is allowed possible due to environmental pragmas which can be added before initialization and hence get compiled on the fly. Which FOR NOW avoids the tricky question: permutation explosions.

logger renderdoc

Improvements:

  • Material parameter lists

  • Base class for renderers

  • Structure for rendertargets

  • Targets are now reusable

  • Added engine rendersettings

  • Common shaderfile

  • Normal generation/combination

A note related to the engine improvements:

Some of the most troublesome things I found I had to deal with is the reusability of rendertargets. Since in the past for each case a target was required a new one was made, which of course means a lot of wasted memory. So to avoid this I made it a point to make them deallocate when not used in a frame or 2. But before that happens they are open for reuse, so that a technique might request targets with certain and most likely similar description and therefore allow for reuse.

Tying into this; the use of materials to do most of the boilerplate related to setting up shaders and so forth was a bit problematic. It was doing a lot of things and had lots of 'if'-statements to handle the off chance that instead of a texture we might be dealing with a rendertarget. The solution was making a targets and texture inherit from a similar base class. And making it so that they can simply be referenced through parameter lists. Which also prevents loads of hardcoding.

Additionally there were a few parameters that had duplicates. So I thought it better to centralize these for easier future use. And due to all these changes it has become a lot easier to spawn many meshes with a diverse amount of material settings.

materialparamscombined materialparamsperpoly

Take a look at some of the code here, on my Github.