Hi guys,
GITHUB: https://github.com/UncleThomy/DeferredEngine
I reworked my deferred engine playground basically from scratch. It started out as a real fast way to make some models appear on screen, but now it has a bit more structure.
What it is:
It’s a scene setup which enables programmers to quickly try out new shaders in a deferred environment with a relatively easy way to import models with physically based materials`
This is the main draw function. As you can see it’s pretty structured and easy to change the rendering or add some shaders.
Speaking of shaders and materials - it’s really easy to have special code for certain materials.
My GBuffer contains the following data:
- Albedo
- World Space Normals
- Depth (z / w)
- Roughness
- Metallic
- Material type
(2 x RGBA + 1x R)
So you can simply set the material type of the helmet visor to an arbitrary number and manipulate pixels with this material type.
An example would be the helmets below which feature a spooky skull hologram made with a simple shader trick.
importing and using objects and lights is really straight forward as well.
public class Assets
{
public Model SkullTest;
public MaterialEffect SkullTestMaterial;
public void Load(ContentManager content)
{
SkullTest = content.Load<Model>("Art/test/skull");
SkullTestMaterial = CreateMaterial(Color.White, 0,0,
albedoMap: content.Load<Texture2D>("Art/test/skull_albedo"),
normalMap: content.Load<Texture2D>("Art/test/skull_normal"),
roughnessMap: content.Load<Texture2D>("Art/test/skull_roughness"),
metallicMap: content.Load<Texture2D>("Art/test/skull_metalness"));
}
}
And then to use in engine
public class MainLogic
{
....
public void Initialize(Assets assets)
{
Camera = new Camera(position: new Vector3(-80, 0, -10), lookat: new Vector3(1, 0, -10));
....
AddEntity(_assets.SkullModel, _assets.SkullTestMaterial, new Vector3(0, 0, -10), -Math.PI/2, 0, 0, 1);
}
}
Culling etc. is handled in a pretty robust way, so you basically don’t need to worry about that.
Adding point lights is similarly easy (I have ditched spot and directional lights for now, they are easy to implement)
public void Initialize(Assets assets)
{
myLight = AddPointLight(position: new Vector3(2, 2, -20), radius: 50, color: Color.Wheat, intensity: 20, castShadows: true, shadowResolution: 1024);
}
I am pretty proud of my frustum culling and shadow optimizations, which i did last night. In a static scene shadows cost almost nothing in terms of performance, which should be expected.
I use cubeMaps for the shadows of my point lights. They are not optimized to the end but have some neat stuff, like for example they will only update the faces that have changing geometry. So if an object moves next to a static light source only 1 or 2 projections are redrawn instead of all 6.
Typically game scenes don’t have millions of polygons around each light source, but with the Stanford dragon and the Sponza atrium, which are very heavy in terms of polycount, the cost for shadowmap generation is a bit inflated.
Nevertheless I can run 10 moving, fully updating lights with pretty big radii, at around 80Hz, which feels pretty good. These are soft VSM shadows by the way (not blurred)
Another thing that makes life easier is a working debug console with Autofill and suggestions
Plus the ability to drag and resize the window to your hearts content
So yeah, just a pet project of mine. Basically redone last night and i like to write about stuff.
I am thinking of making this public if there is demand. It’s obviously still a bit hacky and not perfectly documented (and probably implemented) but it could prove useful maybe.
Anyways - ideas what to implement next?