Global Illumination Progress Update

The Global Illumination by Light Propagation Volumes is progressing in a nice way. Even though this is an artifact in a weird way, it still produces a nice result. The surface is too thin for the grid to not capture both sides. Posted Image But it looks nice.

gi

But not all is good, there’s still weird artifacts:

Sometimes the shadow testing fails when injecting lighting into the grid, I guess this is to do with the resolution but I’m still not sure, I think there’s more to it. Example: The shadow testing should have succeeded, but no indirect illumination is present.

Light Bleeding:

CELL – First try at a scripting language

So, before anyone jumps on the “dont make your own language” wagon, I’m only trying this because I thought it would be an interesting challange and it’d be a great oppertunity to understand how other languages work on the inside.

I’ve attempted it before, but gave up about 20 minutes in, so a few days ago I tried again. But this time I decided to go with boost spirit instead of bison, hoping that it would be easier. And it turned out it was, for me at least. So, the name! The most important part of anything! Right? So I kept thinking about some awesome names, and thought of CELL, but, so then I decided what the C, E, L, L should actually mean. So, I have an engine called Cuboid Engine, thats CE, now LL… Lightweight language! There we go! Cuboid Engine Lightweight Language, brilliant! Now I have to actually create the language.

So it’s a pretty basic setup. Using boost spirit to parse the input, compile it into tokens then do stuff with the tokens which are then translated into instructions, a list of instructions more specifically. These instructions can then be passed to the virtual machine, which works in a “stack” manner.

So it’s still pretty damn basic, but, I got a few things working:

  • Variables
  • Functions
    Arguments, Return values, Multiple Return values ( Which can be of different types )
  • Classes ( No functions yet though Posted Image )
  • External functions ( like in c++, can also be external functions from objects in c++ )
  • Local and Global Variables
    ::var <- local , local : var <- local , global : var <- global
  • If, For and While stuff
  • Logical Operators and and or
  • different assignment stuff ( += , -= *= bla bla bla )
  • And some minour stuff

Examples:

class Foo
{
    ::var = 5; // this works as a static
               // and the // is comments
};

// call external function
print("Foo value:" & ::Foo.var);
function GetAnswer()
{
    return [42];
}

function GetArrayOfAnswers()
{
    ::ans = GetAnswer();
    return [::ans,  ::ans];
}

[::ans1, ::ans2] = GetArrayOfAnswers();
print(::ans1 & ::ans2); // ouputs: 4242
function DoComputation()
{
	::comp = 412 * 0.15 + 0.85 / 43;
}

::max = 50000;
for(::i = 0; ::i < ::max; ++::i)
{
	DoComputation();
}

Yeah you get the idea… Posted Image

Hopefully I’ll get the functions implemented.

Light Propagation Volumes

So a while ago I implemented a pretty neat feature, theres still bugs, due to the voxelization not being “fully” functional. Apperantly when the surface normal is parallel with the camera viewport of the voxelization cameras, the voxelization fails completely.

The following screenshot in the result from the Light Propagation Volume only, the GI Effect is oversaturated for effect and the sponza scene is voxelated using an 32x32x32 grid, so the result is limited, I’ll try later with a higher resolution.

Oversaturated GI

Next Step: Voxel Cone Tracing! :)

A little update

PS. Im no artist, so this is programming art, and, some pictures are deliberately oversaturated, the vegetation looks to be different colors, as the diffuse textures are different. In the 3rd image the engine doesnt clear the depth nor normal textures, so artifacts occur, but in a complete environment there should be no “voids”.
Posted Image
Posted Image
Posted Image

Some progression I’ve made over the months in my engine:

  • HDR Luminance Adaptation ( Pretty happy about this, the only problem is when the areas get too dark, but I’ll think of something )
  • Improved Shadow mapping – Added PCF
  • Better BRDF support, had a few bugs and miscalculations, now vegetation actually looks like vegetation!
  • Better Tone Mapping Support ( Thanks MJP, your samples were a good guideline! )
  • Much better bloom, downsampling by 8 instead of 2, and much cheaper than before
  • Got some better SSAO in, although I’ll re-implement it soon
  • Simple GUI
  • Skinned Animations

Actually I spent a while on the adaptation part, because weird gradients were forming on the screen, turns out that a 2×1 texture for the adapted luminance map isnt a good idea, so I made the mip maps one layer deeper and woala, nice luminance map.

And I’m currently working on:

  • Better GUI
  • Static poses from skinned animations
  • Complete Font Rendering ( Almost done )
  • Light Propagation Volumes ( Its like youre a kid with candy in your hands! )

What I want to implement:

  • Everything!
  • Translucency
  • Subsurfacescattering
  • Destruction module for Physx
  • Apex particles, for some reason it crashes when I enable apex particles, no clue why, so I disabled it for now.

What I still miss to implement from my old engine:

  • Produceal Lens Flares! ( I miss them )
  • Tessellation
  • In world debugging ( Like sphere visualizations for point lights and other debugging stuff )

The gui framework works the same way all my materials does, the artist ( in this case me ) writes a simple shader file, such as:

For a GUI Material:

Some Code up here that the parser doesnt care about

shader "Simple Diffuse"
{
    Properties()
	{
		Info = "Some info that the parser might care about";
	}
	
    // Considered to be global, any input that the shader requires
    // On the native side the slot is fetched by pMat->GetSlot("box")
    input()
    {
		Texture2D box;
		Texture2D image;
    }
	
	pass() // You can have multi-pass materials
	{
		linker()
		{
			// In this stage you could send info from the vs to the ps, or from any stage to another
		}

                vertex()
                {
			// Any transform you'd like to take care off..
                }

		pixel()
		{
			// Set Outlined Shape
			clip((box.Sample(ss, input.texcoord).a <= 0.5) ? -1 : 1);
			
			color = image.Sample(ss, input.texcoord);
		}
	}
}

For a general mesh, more complex:

The parser still doesnt care

shader "Simple Diffuse"
{
    Properties()
	{
		Info = "It might care about this...";
	}
	
    // Considered to be global
    input()
    {
		Texture2D hex;
    }
	
	pass(cull = true; normalmap=true; roughnessmap=true ;)
             // available properties: roughnessmap, normalmap, cull, cullmode, specularmap, dispacementmap, and some minor ones... When enabled, the material will support them.
	{
		pixel()
		{
			output.dffXYZTrA.xyz = hex.Sample(ss, input.texcoord).xyz;
		}

                // available shader stages:
                // vertex, pixel, domain, hull, geometry, linker ( special one )
                // the geometry pass has its own properties, such as:
                // geometry(verticesout = 4; inputtopology = POINT/TRI..., outputtopology.... general geometry specific stuff )
	}
}

An Update

So I havn’t written onto this blog for a while, and there’s quite good reasons for that.

I realized that my engine ran poorly in terms of performance, so I decided to rewrite it, took about 2 weeks to do so, and I’m much more happy with the result, even though not everything is in place, such as the physics system is a bit bugged out, not too much though, but graphically it’s much better, following the footsteps of physically based shading.

And the 2nd reason is that my PC died, the processor was somehow damaged, but I suspect that I was actually given a “broken” pc from the start, as the symptons started early on. So it’s been hard finding any time to program, as I’m currently using an older that does not have support for the newer versions of Directx, which blocks my development for my engine.

Although it’s not because I havn’t been programming at all, I’ve been using my brother desktop for programming when he’s not using it, but he’s rarely away from it, for one reasons, it’s powerful as hell, even though I assembled and selected the parts for it.

And the exams are coming up, which means that I wont have a lot of time for programming or anything close to that, though after the exam period I’m going to resolve the no pc situation.

C++ – The auto key word

A funny remark  which I discovered without realizing it ( Though I’m not the first one… ), is that the auto keyword can be used to access public members with private types, as so:

#include <iostream>
using namespace std;

class FooClass
{
private:
    struct PrivateFoo
    {
        bool m_bFoo;
    };

public:
    PrivateFoo m_Foo;
};

int main()
{
   FooClass foo;

   // The following code will produce an error,
   // you can't access the private type FooClass::PrivateFoo
   FooClass::PrivateFoo* fooPtr = &foo.m_Foo;

   // But this works
   auto fooPtrAuto = &foo.m_Foo;

   // Nothing fancy
   fooPtr->m_bFoo;
   fooPtrAuto->m_bFoo;

   return 0;
}

So as you know, I can’t use the type PrivateFoo directly, because it’s declared as private, but the auto keyword is permitted, even though it detects the type needed and, well, uses it. I see why is technically is permitted, but, logically, it doesn’t give any sense for me, though it might be usable.

BRDF Shading – Cuboid Engine

So lately I’ve been going around optimizing stuff and implementing new cool features. And I’ve also been going around making things more flexible and removing old deprecated things, which is always good. And, one vital thing, is that I discovered that my blurring shaders we’re extremely heavy, therefore I’m now rendering them in 1/4th of the screens size, increasing performance in a mid heavy scene, from 30 to 50-60 fps.

I’ve never really been a fan of the prebaked lens flares, but then I found this amazing person, who has this great algorithm for generating them, or close:

http://john-chapman-graphics.blogspot.co.uk/2013/02/pseudo-lens-flare.html

And the result from this in my engine were better than I expected, so, overall I’m happy with them.

Now on the more serious note, this BRDF shading is a hot topic, and some of it has to do with being physically accurate, and produce great results. So I’ve been reading a bit here and there, but today I tried to implement them, and I’m really satisfied with the result:

Dragon Example, [ Roughness = 0.2, Roughness = 0.5, Roughness = 1.0 ]

d0_2 d0_5 d1

Plane Example, [ Roughness = 0.15, Roughness = 0.25, Roughness = 1.0 ]

p0-15p0_25  p1

General Example [ Roughness = 0.25, Roughness = 1.0 ]

r0_25 r1

 

This shading model looks exiting, I’m definitely going to look more into it!