Welcome to my developer Blog! It focuses among other things on my 3D game engine project. It contains various posts showing my progress over time with videos, gifs, images and texts. Enjoy!

Full screen with random SSAO samples

There we are! The last missing piece was to remove the aliasing that was apparent due to the regularity of the sampling we were doing on every surface fragments. To solve this, a simple method is to rotate the samples around the surface normal of the fragments. That random rotation is calculated (in my case) with shader code applied on the X and Y coordinates of the current fragment (re-using online code snippets).

Finally, to help debug this better (and to show it off now that it is finally working!!!) I added code to switch to a full screen, mouse controlled, camera by pressing enter. Again, this was simple to add, thanks to the quality object oriented design of the project. The feature proved useful since SSAO is subtle. Thus, having a way to zoom in on the models while refreshing the shader code was very valuable:

Full screen rendering of BRDF with 128 SSAO samples

Lots of effort, for a subtle effect... (toggle on/off visible at the 11 and 14 seconds mark)

Time spent for this Time spent so far
5 h 180 h

SSAO support

Finally, I added SSAO (Screen Space Ambient Occlusion) support after 40h of work! It was my first time implementing it, so it took quite a while. I was very close for a long time, but some tricky parts eluded me. I think it was made more complicated for me because of the multi-viewport setup I have. The matrices I used to render to a part of the viewport where incorrect, but it only appeared when I started using them for SSAO. Finding this was quite tricky (especially when you have to come back to this after working all day on something completely different!).

Anyway, here are the results:

If you want some explanation about what is SSAO, you will have to read further!

Time spent for this Time spent so far
40 h 175 h
[Read More]

Render to texture and model cleanup

I did a bit of grunt work as I was getting frustrated with the look of the scene and the usability of the software while working on rendering. This implied a rework of many models making them more colorful, better optimized (removed duplicate vertices and fixed normals) and standardized (they all face the same directions -Z). I could then update my code to work in a more standard way now that models have been oriented properly. I also added a separate debug camera (in the top left corner), and the necessary code to render to texture (which is now displayed on the platform screens).

New models, better debug experience, first steps for deferred renderin

Surface normals visible on the platform screens after pre-calculation

Time spent for this Time spent so far
15 h 135 h
[Read More]

BRDF simulation and mouse movement

This time, I worked on transferring previous work to the project by integrating a shader trying to emulate the BRDF (Bidirectional Reflectance Distribution Function) in real-time. This function represents how much of the incoming light from a specific direction is reflected to an outgoing direction. The idea is: if you calculate it on a specific point of a surface for all incoming directions, for the outgoing direction of your eye, you will get a physically correct simulation of what you would see. While it is currently impossible to achieve in real-time, clever shortcuts and approximations helps get closer to it!

But in short, things look much better now (that is, when models have material set-up, unlike those enemy ships)

BRDF rendering with direct and indirect illumination with single spot light

Computer graphics time-jump... ACTIVATED!

Time spent for this Time spent so far
19 h 120 h
[Read More]

Showing off dynamic window resizing

I realized I haven’t posted it before, but actually the project has dynamic window resizing. I’ve had this feature for a long time (probably from the beginning of the project), but I don’t think I showed it before and it is not trivial to do.

Also, I had to add video support to the Hugo website/blog framework I am using so that it could show videos (the animated gifs were getting too big…).

Dynamic window resizing during execution

It ain't much but it's honest work.

Time spent for this Time spent so far
I don’t remember… 101 h
[Read More]

Reworking object math for big results

After applying the clang-format and beautifying the code yesterday, I couldn’t resist so I ended up reworking the way I store basic 3D object parameters and how they are used to calculate everything. The main point was that I originally used matrices everywhere to avoid having to deal with casting values or overthinking how to optimise for memory/usage. However, it was inefficient and made things harder to debug. This was an issue as I wanted to figure out how to solve the incorrect collision I was seeing when various projectiles where going through their targets instead of destroying them.

Therefore, I replaced these global 4X4 matrices used all over the place with translation vectors and rotation matrix (3X3). I was rewarded quite nicely for it because, after changing the type of values for the translation component of the base spatial object class, collision handling started working as expected!

Animated gif showing a full gameplay loop and accurate collision handling - You don't get hit when you shouldn't anymore!

Redesigning the way we store position solved collision problems

This game is now fair! No more getting hit when you shouldn't!

Time spent for this Time spent so far
6 h 101 h

Multiple shader rendering

After further work I was able to get the rendering handler to support more complex configurations. This allowed me to re-enable the old diffuse shader for each camera, while having the background shader only enabled for the main camera. Shaders are not hardcoded directly anymore in the rendering handler, they are created separately before being registered to it. The rendering flow also is now cleaner, with separate sections responsible for the various rendering steps keeping performance in mind (rendering all cameras using a shader, before moving to the next shader, these kind of things…).

Animated gif showing the background rendering behind the old game rendering - Things are working once more!

New rendering with backgroundshader, main view only

Good to be back! (Except that collision bug...)

Time spent for this Time spent so far
25 h 95 h
[Read More]

Refactoring the rendering system

Coming back after a long break, I wanted to work on improving the rendering. First task was to do some pretty heavy refactoring of the rendering handler to allow it to support different shaders efficiently. This also required changing the camera code to allow application of different shaders on different views. I didn’t want to just hardcode everything, I wanted something more flexible. The animation below shows the work in progress. So, even though the cameras stopped working properly for now, game logic and collision handling continued to work. This shows the value of isolating components and objects and compartmentalizing the game engine properly!

Animated gif showing black screen but game logic still run - Logging shows that events are still happening

Black screen with no rendering but game logic still runs

Also, let's imagine collision bug is fixed! (I will admit though, it looks quite boring now...)

Time spent for this Time spent so far
20 h 70 h
[Read More]

Finishing the gameplay loop

We now have winning and losing conditions enabled via object components (health component). In addition to disabling the object when health reaches 0, the component also sends messages to registered listener objects, most notably the main game object. This is the object which handles the creation of all the assets but now also has logic sending winning/losing messages, dealing with the score and restarting for next level (by re-enabling all the assets and resetting them) and update the score.

However, the UI is very “rough”, since we just print the health and score changes in the text log, and use windows message box to signify victory and defeat.

Animated gif showing destruction of all enemies - Level is then won once they are all destroyed

Shooting the bad guys and getting the winning popup!

Unfortunately, the collision problems are showing...

Time spent for this Time spent so far
5 h 50 h
[Read More]

Projectile and early game logic

Finally working on game logic, with objects interacting together!

Projectiles, just like the other objects in the engine, do not need to be created/destroyed in memory every time we want to use them. Rather they get enabled/disabled, to save execution performance. Additionally, I created a health and a life-time component which when attached to an object become responsible to handle their disabling. Based either on receiving collision messages (you have been hit, so your life is diminishing) or a specific duration (it’s been X seconds, so you disappear).

Time spent for this Time spent so far
4 h 45 h
[Read More]