Cuboid Engine

Cuboid Engine is a graphical rendering framework developed by me over time as a hobby, I simply have one rule:

Keep, Everything, Realtime!

Which essentially means I don’t bake any lighting information, which is a heavy hit on performance and increases the challange! 🙂


The images below do not represent all features but some in the current state of the engine, the first 4 images represent some features of the current state of the engine:

The rendering system follows a deferred path, looking past the regular features of /graphics engines, this engine shines in the following:

  • Cascaded Custom Light Propagation Volumes GI System ( With a Low and High Frequency buffer per cascade )
  • BRDF Shading
  • Luminance Adaptation
  • High Quality Tone mapping (+Bloom Effect)
  • Per LightSource Volumetric Lighting ( RayMarched )
  • Currently Discontinued Screen Space Reflections seen on the law few images.
  • Including a few minour effects that overall contribute to the image

With all features enabled the engine runs at a steady ~100 fps ( ~10 ms ) on my GTX 970 at a resolution of 1920×1080.

The rendering system is based on DirectX 11 and written in C++. It also has a great layer of flexibility, allowing the user to create his own materials without breaking the pipeline (Such as voxelization on any material given), such as:

Shader
{
	// Include the CG Data Layouts
	#include "cg_layout.hlsl"

    // Define the return types of the shader
	// This stage is really important to allow the parser
	// to create the geometry shader for voxelization
	// and also if the user has created his own geometry shader, so that it can figure
	// out a way to voxelize the mesh properly, in this way the user
	// can use ALL stages of the pipeline (VS, HS, DS, GS, PS) without
	// voxelization not being possible.
	// The only problem is well, he has to write the stuff below: ( Even more if he used more stages )
	#set CG_RVSHADER Vertex //       Set the return type of vertex shader
	#set CG_RPSHADER
	#set vert CG_VSHADER    // [Opt] Set the name of the vertex shader instead of writing CG_VSHADER
	#set pix CG_PSHADER     // [Opt] Set the name of the pixel shader instead of writing CG_PSHADER

	// This is his stuff
	// He can do whatever he wants!
	Texture2D T_Diffuse : register(t0);
	Texture2D T_Normal : register(t1);

	// Basic VS -> PS Structure
	// This structure inherits the "base" vertex, stuff that the engine can crunch on
	struct Vertex : CG_VERTEXBASE
	{
		// Empty
	};

	// Now include some routines that's needed on the end of all stages
	#include "cg_material.hlsl"

	// Vertex shader
	Vertex vert(CG_ILAYOUT IN)
	{
		// Zero set vertex
		Vertex o = (Vertex)0;

		// Just let the engine process it
		// Although we could do it outselves, but there's no need
		CG_VSPROCESS(o, IN);

		// Return "encoded" version
		CG_VSRETURN(o);
	}

	// Pixel Shader
	// In this case the return type is FORCED! As it's a deferred setup
	CG_GBUFFER pix(Vertex v, bool IsFrontFace : SV_IsFrontFace)
	{
		// Basic structure containing info about the surface
		Surface surf;

		// Sample color
		float4 diff = CG_TEX(T_Diffuse, v.CG_TEXCOORD);

		// Simple alpha test for vegetation
		clip(diff.a - 0.1001);

		// Fill out the surface information
		surf.diffuse = diff;
		surf.normal = CG_NORMALMAP( // Do some simple normal mapping
			T_Normal,
			v.CG_TEXCOORD,
			v.CG_NORMAL * ((IsFrontFace) ? 1 : -1), // Flip the normal if backside for leaves
			v.CG_TANGENT, v.CG_BINORMAL
			);
		surf.subsurface = 1; // I've got a simple version of some ssss, but it's not very good yet.
		surf.thickness = 0.1; // For the sssss ( Want more s's? )
		surf.specular = 0.35;
		surf.anisotropic = 0.2;
		surf.clearcoat = 0;
		surf.metallic = 0;
		surf.roughness = 0.65f;
		surf.emission = 0;

		// Return "encoded" version
		// Aka compress the data into the gbuffer!
		CG_PSRETURN(v, 	surf);
	}
};

 

PS. Want to see more? Check out the posts.

Leave a comment