Jan 28, 2020 - Some historical videos of Glow engine.

2003-2004

Walkalble visualization of the Ministry of Textile of my home country - I worked on a project with Bouygues Construction, French multinational. The goal was a demonstration of a future buildings to clients.

The whole building:


The room of the minister:


The building was build in 2004

2004

Dynamic stencil shadows, some character animations (and Doom textures)


Initial networking:


2007

The “Tubes” demo, built for one of the Intel game dev competition. Deferred shading, dynamic shadows with shadow maps, particles etc.


Full trailer:


2008-2009

“I know Your Deeds” game demo, 1st and 2nd place winner of Intel Level Up game dev competiton - landscape, foliage, grass, dynamic time of day.


Playing with dynamic navigation meshes:


“Little Zombie Susie” game demo, not finished submission to IGF:


2010

Little engine and demo, optimized to run on Samsung TVs of that time:


2014

Voxel tank game “Iron Cube”, wild mix of Minecraft and World of Tanks:


2015

Little game, prepared in 2 days for Ludumdare competition:


HBAO - ambient occlusion:


2017

Voxel game prototype, made in collaboration with @Sir_carma:


Oct 16, 2019 - Pathtracing - Day 1

Ray Tracing in One Weekend

I was reading the excellent Ray Tracing in One Weekend and decided to give it a try with my voxel engine/editor. The book uses spheres as primitives for a scene, but I wanted to use voxels.

How it works

A ray is launched from a camera to each pixel on a screen, intersection with a scene is found, we calculate where this ray will go further. For a diffuse surface, a ray is scattered in a random direction, metal surfaces reflect a ray, glass reflects or refracts it. Better explanation is in the book.

Ray casting

Performance of ray tracing depends on how fast is your ray casting - there are multiple techniques to optimize it - hierarchical bounding volumes etc. Luckily, the engine already had world trace function, which was used for surface editing, although it was inefficient.

So the first thing I implemented was modification of Bresenham’s line algorithm for tracing, similarly to Wolfenstein 3D, but extended to 3D. Here is a good explanation of a raycasting used in Wolfenstein - basically you incrementally jump from voxel to voxel looking for a first solid voxel. If a voxel is solid - we found our intersection. As the voxel field is split to 32x32x32 voxel clusters, we can skip empty clusters to optimize a tracing. Same technique is used to jump between clusters. Only 2 conditions and 2 floating point addition is used in the internal loop for both clusters and voxels.

Shading and Lighting

After that I switched to actual rendering - basically re-implemented shading described in the book in 300 lines of code. Ray tracing is a quite powerful technique, allowing you to render a picture quite close to reality with few lines of code.

For calculating sun lighting and shadowing, I used importance sampling, similarly to the idea from Ray Tracing: The Rest of Your Life.

One of the first images (using free voxel scene by Mike Judge):

Optimizations

Initial implementation was slow - 0.4M ray per a second, several minutes to render 720p picture with 100 samples per pixel, so I decided to optimize it, applying obvious solutions:

  • multi-threading - rendering an image using several threads by collecting resulting colors in a single floating point buffer - it helps to get initial picture really quick.
  • cleaning profiling/debugging code - trace() function is called million times, so removing everything with a mutex helps a lot
  • better random number generator: from the article by Aras.

Random number generator and multi-threaded rendering was a pain initially - I spent couple of hours trying to understand why the picture rendered with 100 pixel per sample looking so bad:

The answer was quite interesting - basically random function generator in C++ uses math algorithm to get next random number and you need to call srand() to initialize the generator in each thread! The random number generator is used to shift a ray in a random direction for each sample, but without srand() it was just going in the same direction, so each pass produced identical image.

Conclusion:

I was able to optimize ray tracing from 0.4M rays per a second to something around 5M rays per a second with a couple of tricks. Further optimization could be tricky. One possible solution could be using Intel® Open Image Denoise which helps to render with a fewer samples per pixel and run denoiser on top.

Oct 16, 2019 - Running emscripten apps in fullscreen

I spent an evening making my emscripten game demo working in full screen mode. So basically, Emscripen supports 2 modes - “proper” fullscreen, and soft fullscreen. First one is similiar to a fullscreen mode of a native app, but it seems not supported in all browsers. Soft fullscreen is just running the app fully resized in the browser window, and it’s exactly what I needed.

It is 2 steps, assuming SDL2 usage for a platform layer:

1) switch to fullscreen after SDL window is created

	if (fullscreen){
		EmscriptenFullscreenStrategy strategy;
		strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
		strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
		strategy.canvasResizedCallback = emscripten_window_resized_callback;
		strategy.canvasResizedCallbackUserData = this;   // pointer to user data
		emscripten_enter_soft_fullscreen("canvas", &strategy);
	}

“canvas” is the name of html element with game’s main window (it’s default in Emscripten shells)

2) create a callback to handle window resize event

EM_BOOL emscripten_window_resized_callback(int eventType, const void *reserved, void *userData){
	METHOD();

	double width, height;
	emscripten_get_element_css_size("canvas", &width, &height);

	int w = (int)width, h = (int)height;

	// resize SDL window
	Platform* platform = (Platform*)userData;
	SDL_SetWindowSize((SDL_Window*)platform->get_wnd_handle(), w, h);

	// engine-specific code - internal render size should be updated here
	event_t e(ET_WINDOW_SIZE, w, h, timer::current_time());
	LOGI("Window resized to %dx%d", w, h);
	platform->on_window_size_changed(w, h);
	return true;
}

Oct 10, 2019 - Emscripten


I ported my demo game “Iron Cube” to the web in couple of days using amazing Emscripten technology. The demo could be played here https://glow3d.com/blog/demos/iron_cube.html and should work in any modern browser, including mobile.

Aug 31, 2017 - IMGUI


Initial support for themes + Linux, MacOS and Windows build support. https://github.com/yak32/glw_imgui

IMGUI is a code-driven, simple and bloat-free GUI system, widely used in modern game engines and games. Best explanation of IMGUI concept is here. The library has basic suppot for layouting (attachable toolbars, layout serialization), themes (colors and serialization), lock-free multithreading (triple buffering).

This library was a part of my game engine, but I extracted and moved it to github some time ago.

May 7, 2017 - Voxel adventure game.


A youtube video from the voxel game prototype I built on my Glow3D engine some time ago. The idea was something like the original Zelda game (isometric, adventure, but on voxels). Art from the video was created by Sir carma. I built a parser of the MagicaVoxel file format and updated significantly the source code I created for the Iron Cube game. Support for nVidia HBAO+ and nVidia Shadows was added using Shadow Works middleware to improve picture quality. nVidia HBAO+ is Screen space ambient occlusion technology to emulate global illumination and I gave up on creating my own implementation of SSAO (at least for some time). I have some support for shadows in the engine but I didn’t have efficient Cascaded Shadow Maps at that time and decided to use nVidia libraries instead. It’s efficient and used in many modern games.

MagicaVoxel is a nice voxel editor and renderer, created by @ephtracy. He basically did the 3D Studio Max alone but only for voxel graphics. The sound used for the video is Medieval Introduction.

May 2, 2017 - New website and blog

I spent several evenings on rebuilding my website and blog - www.glow3d.com. The first platform I used to write periodically about my hobby game engine was blogger.com. I started it several years ago, but for some reason decided to switch to AWS based website and WordPress - basically the only reason was to learn basics of html and web site development. Also, I wanted to try it as a server for my prototypes of multiplayer games. WordPress-based blog was bad - SQL database periodically crashed for some reason and I had no idea why (probably memory configuration). I was tired and cancelled my subscription to AWS services (honestly the main reason was the expiration of the free period) and closed the website and blog.

To rebuild it I decided to use Jekyll - a static site generator, written in Ruby by Tom Preston-Werner, GitHub’s co-founder. It’s called ‘static’, because websites created using this technology don’t have SQL databases, complex scripts etc. It’s fast, simple and blog-oriented. Also, it natively supports Markdown with syntax highlighting for almost every programming language. You basically compile your Markdown posts, templates to the final static site and GitHub can be used to serve a site for free. This was exactly what I needed.

Jekyll is relatively mature technology, started in 2008, so it’s easy to find templates for a website. I liked the design by the company html5up and it’s under the Creative Commons license. I started from the simple Jekyll-based blog template Jekyll-Now and applied the html5up theme on top of it a day later. Some additional pain was the porting of my old blog, exported from WordPress to Markdown but I used some scripts. This link is useful to port WordPress blogs to Jekyll.

I used Disqus for comments originally but afterwards this article (shortly - 105 additional network requests and a ton of tracking for some shady sites) replaced it with Facebook comments. The source code for the website and blog can be checked on my GitHub account here.

I hope that no exciting new technology will appear soon and I will not port this site to it again.

P.S. The broken English of the old blog was fixed by my 9 year old son, who is the winner of his school’s Spelling Bee competition. Now he is my fulltime editor.

Apr 21, 2017 - Ludum Dare

“Pied Piper” – stupid little game about dancing zombies. It’s my first attempt to participate and finish a game for Ludum Dare.

What went right – The idea to use Fuse tool for characters and mixamo.com for animations really saved time. It’s easy to make a realistic character in Fuse and I prepared a pipeline for exporting characters from mixamo.com to my engine before Jam. Also, making the game was a lot of fun (really loud laughing for the first 10 minutes when I saw the first dance) and it was an important motivation to finish it.

What went not so right – planning (as usual) – I spent one evening on selecting proper music from freesound.org and had only one evening and night to actually write the code. As usual, I found several weird glitches (downside of the usage of my own engine). One glitch leaked to the first release for LD (and fixed in the latest version)

This is my first LD, so the goal was just to finish something. Engine is mature now and can be used for next LD. I’ll probably continue to work on Pied Piper if I receive positive feedback from the community.

Youtube video of the latest version is here

Apr 20, 2017 - Voxel project

Some time ago I worked with excellent voxel artist Sir carma. This is a screenshot from that project, the art + glow3d rendering.

Dec 20, 2014 - DirectX 11

Screenshot of the editor with DirectX 11 renderer and simple scene with 2 light sources.

I added support of DirectX 11 to Glow engine, which took me couple of weeks. DirectX 11 seems much simpler and better designed than DirectX 9, with less calls to the graphics driver. Source code now is 2 times more compact than the DirectX 9 version. Still, DirectX 9 is supported, and nothing is broken.

I started support for DirectX 11 with hope to fix my issues with Oculus SDK.