Fourteen months after

Yeah, fourteen months have passed since my previous post, that’s a lot of time.
A time apparently spent doing nothing, if you just look at the activity here, but in fact I was quite busy in real life.

Exactly fourteen months ago I found a job in the game industry, as my LinkedIn profile can testify, and now working on video games is what I do every day. Having the job of your dreams brings satisfactions (like being on MobyGames, the IMDb of games ;) ), but it also brings, as many other jobs, a constant lack of spare time.
If you want to have part of it back you have to focus and careful organize your time, something I’m beginning to understand and practice lately.
A proof of this is in one of my latest Google+ posts, which unfortunately is not public. :P

Yeah, Google Plus. In fourteen months we have seen many things happen, like the birth of this new social network (for which I already have a profile), the release of Linux 3.0, a new major number kernel with no major features ;), but also my switch, after years spent on Gnome and NVIDIA, to KDE and AMD. :o
Don’t worry, this applies only to my new netbook, which have also stolen the title of fastest OpenGL device at my disposal from my Optimus One Android smartphone. :P
Photon is still alive and kicking of course, but it is not in the city where I work, so they are now my developing machines: the first allows me to even test GL4/D3D11 features, while the other is used for mobile programming.

Last, but not least, the site have been revamped and now everything is handled by WordPress.
This is far more easy and effective than having a separate Drupal site with the hassle of maintaining it but without exploiting any of its powerful CMS capabilities.
Now I have got to go, see you in another fourteen months. Just kidding. :P

Close to deferring the deferred demo post…

Yeah, I was quite close to postpone the writing of this post to tomorrow, but I won’t. :)
The title is humorous but clear, my last demo deals again with deferred shading.

GLSL_deferred with SSAO, iterative parallax mapping and Depth of Field

This time I made every effort to do things right: there is support for directional, point and spot lights and, much more important for performances, lights are rendered only inside their influence volumes using projective texturing.
This means that while directional ones affect everything and have to be rendered as full screen quads, point lights are only rendered as cubes and spot lights as pyramids.

Comparison between disabled and enabled SSAO

This is slightly different from the usual approach taken, which uses spheres and cones but is also a bit more vertex heavy. :)
Rendering bounding shapes should barely affect performance, but makes the check for camera position a bit different.
The check is disabled by default as it is sufficient to cull front faces and invert the depth test to avoid double lighting issue and benefit from some depth optimization.
By enabling the check the application will expose my poor approximation of checking if the camera is inside a pyramid by using a formula meant for a cone, so better if it stays disabled, while the volume is not intersecting the far plane everything should behave as expected… :D

Comparison between normal mapping and iterative parallax mapping

The demo is also a bigger attempt into effects integrations, it will serve as a test bed for a more organized and high level framework.
As a matter of fact it also features Screen Space Ambient Occlusion, Iterative Parallax Mapping and Depth of Field.
Very cool stuff, but I already have a list of things that I would like to implement sooner or later, like a Light Pre-Pass, a couple of advanced shadow mapping techniques, the integration of water rendering, HDR illumination and the reconstruction of position from depth.

Normal rendering and Depth of Field blur

I have published the sources and a video (Vimeo | YouTube), that for the first time comes with a nice soundtrack: it’s Nova Siberia by Big Giant Circles (Jimmy Hinson) from OverClocked ReMix! ;)

Note: I have had a hard time with glc, x264, mencoder and ffmpeg but still YouTube doesn’t accept my video together with the sound, at the moment I have uploaded a mute version.

Spring Updates

Just like I did the past summer, I’m writing this update post to summarize the latest goings-on. ;)
First of all the Episode One of the IndieVault Podcast (Italian) is online, and that is important because I will be one of the voice you are going to hear in every episode. ;)
One of its topic is the IndieVault Conference at Gamecon 2010, held on April the 30th at Castel Sant’Elmo in Naples.

I have participated as a Lowpoly Studios coder but my presentation (Italian) was equally covering my internship experience as well as the indie one.
You can find all the episodes (yes, there is an Episode Zero too ;)) on iTunes.

Going back for a moment to Lowpoly Studios I have got to point out the last M3xican post on our official developing blog (
A new graphic style…
) along with a new video (The Undergrounder: Level Editor BETA 4 + New graphic style).

Talking about new releases, I was going to forget that PacStats 0.1 is out!
Have also a look at its new Freshmeat, GnomeFiles and Softpedia pages.

Last but not least, while I still don’t have the time and the patience to make a complete source release, I have made the first step publishing a couple of videos from my internship activity at Raylight: the first one (YouTube | Vimeo) has been taken from the final demo, while the other (YouTube | Vimeo) is a simple yet nice test that I’m pleased to show.

PacStats revamped, enhanced and published

Many months ago I was dealing with OpenGL, shaders and C++, the usual tools of a graphics programmer wannabe. :)
This time I’m writing about something completely different, the recent developments of PacStats.

The new PacStats logo

PacStats is a 2007 project that was born as a toy experiment borrowing a lot of GL O.B.S. code: it is a program that analyzes the log of pacman, the ArchLinux package manager, and then plots a bunch of statistical charts about its activity.
Have you ever wandered how many packages have a name that begins with the letter “F”, or who is the packager that has contributed the most? With PacStats you can easily answer to those questions. ;)

But what have been the main changes since 2007?
Well, first of all I have renewed the code as already done for GL O.B.S., so the GUI is now based on GtkBuilder, Matplotlib imports NumPy and the Python print statements have been converted to functions.
The program have also gained a toon shaded Blender made logo, and the possibility to be installed thanks to distutils through a very simple PKGBUILD that is already on AUR.
While some tables of the database have been refactored, the parsers made more robust and the base/derived chart classes relationship more polished, the most important news for the end users are represented by the possibility to configure the program through the GUI or a text file, the addition of a database information window and a menu item to optimize it and the addition of a couple of new charts and a toolbar to control them.

The Preferences window


The Database Information window

The original project have been hosted for a long time on my personal site, but the efforts spent to reboot it have suggested the possibility to have it published in a more “official” way: as a matter of facts you can find it on Google Code.
I have been interested in this open source project hosting platform for a long time and until now I’m really satisfied by its streamlined yet flexible interface.
I’m also very glad to have employed Mercurial for source revision control, after having been positively struck by the git experience and been advocating distributed systems for quite some time now, my decision to use it instead of Subversion feels very natural. Sure enough it is a really nice tool, easier to grasp than git but capable of most of the things of its famous contender, written in Python but yet not suffering too much when coming to performance.
Just like every other free software I have been responsible for, I have created a project page on Ohloh too, have a look at it and enjoy your charts! ;)

Gimme some (real-time) water!

Computer generated water has always interested me, since the days of POVRay on Amiga I was trying to simulate it in some way.
Some days ago, while studying another technique, I put everything aside because in that particular moment I felt the urge to implement a water shader. :D

water_crop

I began looking for existing implementations and I found Reimer’s XNA tutorial, a simple approach which I think could be optimized, but that already provides a nice looking water.

The technique is composed of four passes:

  • Rendering the reflection map
  • Rendering the refraction map
  • Rendering the scene
  • Rendering the water plane linearly interpolating the two maps with a Fresnel term

One of the drawbacks is represented by the fact that the whole scene is rendered three times during the first three passes, I’m sure that this procedure could be optimized, but I was lazy enough to cease any further test. :)
Moreover having every pass clearly separated helps with debugging and makes the application capable of displaying them one at a time.

The scene is rendered with parallax mapping enabled, and that is more evident than ever thanks to the new bricks textures, but with an altered shader that also performs user plane clipping, decisive for the first two passes.
Talking about the Fresnel term I have implemented a naive (nothing more than a dot(V, N)) and a better approximation based on the Nvidia’s Fresnel reflection paper.
In the source you will find both but only the first one is actually used, it works better in the scene used in this demo.
You can easily see that waves are fake, the water is composed of just two triangles, the ripple animation is generated by the fragment shader altering texture coordinates based on a normal map and using a time variable.

Of course you can have a look at videos on YouTube (GLSL_water, GLSL_water_HD) or Vimeo (GLSL_water, GLSL_water_HD) and download the sources.

High Dynamic Range galore

In January, during my internship activity, I was researching in the field of HDR imaging, today I had the time, at last, to polish a bit and release the two demos I made at the time.

They both load an RGBE image (the two you see here are courtesy of the Paul Devebec’s Light Probe Image Gallery) through the library of Bruce Walter.

Light probe at different exposure levels (hdr_load1)

Light probe at different exposure levels (hdr_load1)

The first demo implements the technique described in the article High Dynamic Range Rendering published on GameDev.net and is based on five passes and four FBOs:

  1. Rendering of the floating-point texture in an FBO
  2. Down-sampling in a 1/4 FBO and high-pass filter
  3. Gaussian filter along the X axis
  4. Gaussian filter along the Y axis
  5. Tone-mapping and composition

The algorithm is very simple, it first renders the original scene then it extracts bright parts at the second pass, which merely discards fragments which are below a specified threshold:

// excrpt from hipass.frag
if (colorMap.r > 1.0 || colorMap.g > 1.0 || colorMap.b > 1.0)
	gl_FragColor = colorMap;
else
	gl_FragColor = vec4(0.0);

While the third and fourth passes blurs the bright mask, the last one mixes it with the first FBO and sets exposure and gamma to achieve a bloom effect.

// excerpt from tonemap.frag
gl_FragColor = colorMap + Factor * (bloomMap - colorMap);
gl_FragColor *= Exposure;
gl_FragColor = pow(gl_FragColor, vec4(Gamma));
Light probe at different exposure levels (hdr_load2)

Light probe at different exposure levels (hdr_load2)

The second demo implements the technique described in the article High Dynamic Range Rendering in XNA published on Ziggyware and is based on seven passed and more than five FBOs:

  1. Rendering of the floating-point texture in an FBO
  2. Calculating maximum and mean luminance for the entire scene
  3. Bright-pass filter
  4. Gaussian filter along the X axis
  5. Gaussian filter along the Y axis
  6. Tone-mapping
  7. Bloom layer addition

This approach is far more complex than the previous one and is based on converting the scene to its luminance (defined as Y = 0.299*R + 0.587*G + 0.114*B) version, the mean and maximum value can be calculated using a particular downsampling shader and working in more passes, at each one rendering on an FBO with a smaller resolution than the previous until the last pass, when you render the luminance of the entire scene on a 1×1 FBO.

As usual you can have a look at YouTube (GLSL_hdrload1, GLSL_hdrload2) or Vimeo (GLSL_hdrload1, GLSL_hdrload2) videos and download the sources.

GL O.B.S.: two years after

You’re reading about GL O.B.S. after *exactly* 730 days (I swear it was not made on purpose ;-)): today revision 50 has been committed.
No new feature has been added, I’ve dedicated the efforts of the last days to a case study about updating an application after a very long time, the process mainly involved removing deprecated things and adding support for new ones.

GL O.B.S. GUI is now based on GtkBuider

GL O.B.S. GUI is now based on GtkBuider

Let’s read together some lines from the revision log:

  • GUI migrated from libglade to GtkBuilder
    This was, with no doubt, the most time consuming task: gtk-builder-convert tool was not so reliable and I was compelled to recreate the GUI from scratch with Glade. I have also set the minimum GTK version required to 2.16
  • using JSON format for storing benchmark information dictionaries
    This feature is a way to get rid of the deprecated execfile() built-in function, instead of executing a python script to read a dictionary, the Benchmark class now parses a JSON file with the new integrated json module.
    Comparing an old and a new file you can notice how simple it was the conversion, I’ve only lost the ability to comment a line. ;)
  • importing numpy instead of numerix in matplotlib
    This is another deprecation related issue, matplotlib is now based upon numpy.
  • matplotlib canvas get refreshed instead of being destroyed and then recreated
    I don’t know why two years ago I was destroying and recreating the object instead of just calling the draw() method every time it had to be refreshed. :-D
  • some more attributes and objects integrated in the GtkBuilder XML file
    I’ve integrated more attributes in the XML GUI file, like default size for secondary windows or Paned positions.
    Moreover, thanks to GtkBuilder, even some objects have been integrated, like Adjustment or TextBuffer.
    Actually also TreeModel objects should be configurable inside Glade and integrated inside the XML, but I didn’t manage to make them work. :-)

Other remarkable changes in the field of Python3 future support and deprecated features removal were:

  • all the print statements converted to functions
    Well, we all know the content of PEP 3105;-)
  • using hashlib.md5 instead of md5
    The md5 module has been deprecated in favour of the hashlib one
  • using “key in dict” instead of dict.has_key()
    The has_key() method no longer exists in Python 3
  • using subprocess.Popen instead of os.popen()
    os.popen() have been deprecated in favour of the subprocess module
  • using urllib2.urlopen() instead of urllib.urlopen()
    Another deprecation suggested substitution, from urllib.urlopen() to urllib2.urlopen()
  • removed “copyright” argument and added “classifiers” in setup.py
    The distutils.core.setup() function loses the “copyright” argument but gains “classifiers”. :-)
  • dropped support for pysqlite2 and old webbrowser module
    Now that the minimum requirement is Python 2.6, there is no need for pysqlite2 or old webbrowser module support
  • I have also removed the deprecated Options class in some SCons scripts.

I’m not sure I will have some time in the future to continue developing, but this was a nice “reboot” and I also have some new ideas in my to-do list. ;)

A flexible PLY loader for Evolution War r71

I’ve cited Evolution War for the first time on this blog in my previous post, today I want to celebrate my return to SVN committing after a very long time. :D

PLY Export

Revision 71 adds the support for a real Stanford PLY parser and loader, while the one I coded for my graphic class library is very primitive, expecting a hard-coded order for data, this one shouldn’t have any kind of problem with every well-formed PLY file.

For example, while the hard-coded loader can only accept a file like this:

ply
format ascii 1.0
comment Created by Blender3D 249 - www.blender.org
element vertex 4
property float x
property float y
property float z
property float nx
property float ny
property float nz
element face 3
property list uchar uint vertex_indices
end_header
1.000000 2.000000 3.000000 -4.000000 -5.000000 6.000000 
-1.000000 -2.000000 -3.000000 4.000000 5.000000 6.000000 
1.000000 2.000000 3.000000 -4.000000 -5.000000 6.000000 
-1.000000 -2.000000 -3.000000 4.000000 5.000000 6.000000  
3 0 1 2 
3 1 3 2 
3 4 2 1 

the parser loader can load even something like this:

ply
format ascii 1.0
comment Created and shuffled by hand
element face 3
property list uchar uint vertex_indices
element skipme 3
property float skipfirst
property float skipsecond
element vertex 4
property float z
property float nz
property float y
property float ny
property float nx
property float x
end_header
3 0 1 2 
3 1 3 2 
3 4 2 1 
0.0 0.0 
0.0 0.0
0.0 0.0 
3.000000 -6.000000 2.000000 -5.000000 -4.000000 1.000000 
-3.000000 6.000000 -2.000000 5.000000 4.000000 -1.000000 
3.000000 -6.000000 2.000000 -5.000000 -4.000000 1.000000 
-3.000000 6.000000 -2.000000 5.000000 4.000000 -1.000000 

But one of its most important feature resides in the ability to correctly load binary PLY files! :)

Related to it there’s a bug I would like to share with you together with the fix:

istream& istream::read (char* s, streamsize n);
[...]
ifstream ifs;
unsigned int *uIndices;
[...]
ifs.read((char *) uIndices+(j*3), sizeof(unsigned int) * 3);

The read() method only accepts char pointers, so uIndices is casted, but the precedence goes to casting and not to native unsigned int pointer arithmetics, leading to catastrophic effects! :o

The fix was as simple as the bug was subtle:

-ifs.read((char *) uIndices+(j*3), sizeof(unsigned int) * 3);
+ifs.read((char *) (uIndices+(j*3)), sizeof(unsigned int) * 3)

Summer summary

This post tries to address the recent lack of blog updates presenting a summary of remarkable dates occurred during this summer. :-)

Summer Collage

  • 3rd June – I registered a Twitter account, you can read about me and gamedev at a faster pace.
  • 1st July – Me and M3xican announced the development of the independent game Evolution War and registered the Lowpoly Studios domain.
    Check also the related Twitter accounts: EvolutionWar and LowpolyStudios.
  • 22nd July – I got a Bachelor’s Degree in Computer Science with higher marks and honours from the “Federico II” University of Naples, Italy. :-D
  • 3rd August – The Khronos group announces the release of OpenGL 3.2 specifications at SIGGRAPH 2009, at last it comes with different profiles support!
  • 10th August – I bought the “10 Top Indie Hits” on Steam: great games at a great price!

Yet another toon shader

Maybe is true, as I wrote in the README file, that I coded this demo because I felt like the only one who hasn’t yet implemented a toon shader. :)
Actually this is not the only reason, I came with the inspiration when I was presenting the first part of my updated Modern GPUs slides at the university, this time the event was organized by some students and advertised with leaflets. ;)
So, for the second part that will be held next Wednesday, I’m planning to integrate the explanations about the internals of this demo.

From untextured to textured with outlines

From untextured to textured with outlines

It was easy and fast to have a basic toon shader working, thanks to the Lighthouse 3D tutorial.
This version uses a cascade of if-then-else instead of a more usual 1D texture lookup but, judging from the tests I have run, it’s not a performance issue, at least on GeForce 8 and newer cards.

For the edge detecting I wanted to exploit the fragment shader capabilities, working in screen space with the sobel operator and thus being independent from geometric complexity.

The only problem was about *what* to filter.

  1. The first test was straight, I filtered the rendered image, a grey version of the textured and lit MrFixit head, but the results were poor: edge detecting outlined toon lighting shades too.
  2. In the second one I decided to filter the depth buffer, I could get rid of colour to grey conversion but, again, the results were not satisfactory: there were no outlines in the model, just a contour all around.
    Maybe it could have been corrected with a per-model clip planes tuning, but I gave up.
  3. With the third test I filtered out the unilluminated color texture and the results were better. Unfortunately it relied on the presence of a texture and outlined too much details.
  4. I think the fourth approach, as seen in this demo, is the best one.
    I used MRTs to save the eye-space normal buffer during the toon shader pass, then I filtered a grey version of it, outlining the contour plus some other geometric details.

A small note: saving an already grey converted buffer in the toon shader pass speeds up the demo a bit, but storing the normal in a single 8 bits component of the texture causes a loss of precision that leads to some visible artefacts.
Using a floating point texture helps with the precision issue but makes the demo too slow.
Maybe I should try using a single component texture or some kind of RGBA packing algorithm…

As usual you can have a look at YouTube or Vimeo videos and download the sources.