This page presents a few of my personal projects in reverse chronological order, accompanied by some summary of my programming history.
All these projects were made before my professional career, and as this portfolio was put together in the spring of 2013, some content may be currently outdated.
Lately, I've worked with Unity 4 and its DirectX 11 -level features, such as tessellation and the deferred rendering pipeline. Since I've been working with Unity, I've used quite exclusively C# and Cg for the most of the latest projects, but be it C++, HLSL or GLSL, it will hardly be a problem to change the language, since my C++ -experience spans over 15 years and I've used DirectX and OpenGL for a decade. In the near future, I'm also interested in learning how to use compute shaders.
This flyby demo was made almost entirely in some two or three weeks for a competition, where the entries had to present graphics techniques made possible by the new DirectX 11 support in Unity 4. The demo takes advantage of DX 11 techniques such as tessellation. Since I had the trial for only 30 days, I had to make everything quickly, and I have hardly made all possible performance tweaks to the demo. Also, some of the shaders were made exclusively for the deferred rendering pipeline available with the Pro license of Unity 4.
One of the features was tessellated meshes deformed along Bezier paths. The tubes in this picture consist of parts that originally have only 56 quad faces each (that is, 112 triangles), and they have been tessellated with PN-triangle tessellation. Also Phong tessellation had been implemented, because the tessellation caused problems with my laptops nVidia card.
Another main feature was fake water flow animations. Simply put, the flow is defined as a grayscale texture, which is "thresholded" with the smoothstep() shader function, and then converted into a heightmap with some nice tweaks.
A less visible technique in this demo is the varied texturing of walls, ceilings and floors. This is a (downscaled) two-texture "atlas" of wall textures. From this texture, the wall shader can fetch two samples from the same pixel row (maybe cache-friendly), and then mix those based on a 3D noise texture generated earlier in the program. With proper parameters and "smooth thresholding", this easily breaks some wall texture patterns and creates new ones.
The ending scene of the demo had animated branches growing from the ground to form, for example, a bridge and the name of the demo. This "branching" technique was partially borrowed to the "Tree fo' life" game below, but without the tessellation to make the game DX9-compatible.
Video of the demo (720p, but quality not awesome, because of the compression and recording overhead):
The included project is a Unity 4 Pro trial project, which requires some Pro license features, but you can still check out the Cg shaders and C# sources from it in any case.
This section just presents tools and effects I've made in more detail. Some of these are in use in the Pipe Dream demo.
This video shows the Bezier path tools, and how the path deformations work. In the first part of the video (as well as in the "Tree fo' life" game), some of the branches/roots coming from the ground (not the "bridge" thing) are made dynamically based on mouse clicks/dragging. The path data is "baked" to a texture, which requires a calculation delay of only 5 to 50 ms on a decent computer.
To check the C# source code, find BezierPath.cs, BezierPathEditor.cs, and PathTextureBakery.cs in the PipeDream or TreeFoLife Unity projects for the main script parts. There are multiple Cg shaders for the path deformation/animation in the projects as well (Check PathAnimation*.shader files and PathTess*.cginc files).
The video below shows how the fake water flows can be used. The technique is very simple: a grayscale image is smoothly "thresholded" with the smoothstep() shader function so that a short part of the grayscale image becomes a linear "buffer". This linear buffer can be turned into a more round one with a function like sqrt(1 - value * value), and then the result can be combined with a noisy wave texture to create a "heightmap" for a mesh that is almost a copy of the floor itself. The animation itself is just a matter of updating the phase parameter of the shader. An example image used for a water flow can be seen on the right: It represents the last water flow of the Pipe Dream demo.
This video presents just a technique for creating variation in textures (used a lot in the Pipe Dream demo: walls, floors, ceilings & tubes). The idea is to generate a 3d texture, which is sampled first from the world position and then with the transformed result. The sampled value is thresholded with a smoothness parameter to create a grayscale map which can be used as a mask between two different textures. The textures can be similar (clean wall & dirty/cracked wall) or very different (metal & rust as in the tubes of the video).
I've made some other experiments with Unity as well. Below is a short composition of a few of them.
A small game for GGJ 2013, where the player collects water drops for a tree. Unity 4 pro trial was used to create the project, but it should only use features available with the free license. The zip file is the actual GGJ 2013 package, so it has the CC BY-NC-SA 3.0 license.
Some gameplay footage:
In 2012, the most notable projects were graphics engines experimenting on the OpenGL 4+ and DirectX 11 APIs, and a university course project made with Unity 3, in a group of three students.
Although I have programmed with OpenGL and DirectX since 2003 or so, this year marked a small change in my game development. Last year I've refined my understanding of game and graphics engines, but also changed my focus back from engines into actual games. While I have made many engine-style projects, it hit me quite strongly that some of the latest game projects have stalled into the phase of refining engines and making toolsets. Albeit being an enthusiastic engine coder as well, after reading and applying knowledge from books such as "Game Engine Architecture" and the 4th edition of "Game Coding Complete", it finally started to become evident that I must take a deeper look into making games with existing engines instead of wasting years just to never finish a perfect game engine. Thus, I spent the last few months of 2012 focusing heavily on gameplay and graphics programming with the Unity engine.
I had also some interest towards the new C++11 features, some of which are used in the latest projects made with C++.
Being interested in learning the new OpenGL (3+/4+) features and the differences to the latest DirectX API, I started a new project. Another source of inspiration for this project were books such as "Game Coding Complete" (4th edition), and "Game Engine Architecture".
This project uses a few libraries, namely GL3, GLEW, GLFW, GLM, stb_image, tinyxml2, and zlib, but all of them are included with the project, so it should be buildable without external requirements. Note that as this is a development version of an unfinished project, it is provided for review purposes only, and is not to be distributed further. The main reason behind this is that there are small parts of code from other sources, and the requirements for a proper license have not been thoroughly thought through, as the project was originally made for experimentation purposes only, and not for distribution.
Why this project ended? Later in the autumn 2012, the need for a proper toolset and the lack of time turned my attention to existing engines. At this point it was more than clear that I'd never get to productive gameplay programming with my own engine. I did have plans for a C# scripting engine and a toolset made with C#/Windows Forms, but I guess the development of the tools would still be in progress, since I still have had my studies taking most of my time. The most logical choice was to start development with Unity3D, because it gave an engine similar to what I attempted to make, and to some extent I could even use Unity in my CS studies. Luckily it didn't take long until Unity 4 was released, so I got a new chance at programming DirectX 11 -level hardware.
Just as with the DX11 engine, on this project I concentrated on the engine-side of programming, not on the content. This picture shows an animated mesh (not modeled by me) with its bounding box, and some other test objects.
This project was made by a group of three students, and in it, my task was coding, 3d graphics, and being the project lead, since the other members were not very experienced in game development. The other members concentrated on areas such as game & level design, and the sounds of the game. For me, this was an introduction project to Unity, so the engine features could surely be used better, but at least the finished product is quite a decent game.
Note that the project was made by a larger team, so the game and its sources are given here for demonstration purposes only.
To get a better understanding of the DirectX 11 API, I started to create a larger project with it. I made such a project in 2011, and this one as its spin-off during spring and summer of 2012, but I hardly had any time to invest in it then. Soon after, as I wanted to explore the corresponding features of the new OpenGL versions (3.3, 4+), I started a different project which left little attention to DX 11 for a while.
Note that this project has external dependencies, such as the Effects11 library, which has to be separately built, if you want to link the program (shouldn't be necessary, built executables are provided in the zip package as well).
Until early 2011, I had had some suspicions towards C#, whatever the reason may be. However, in the spring 2011 my first touch with C# convinced me that it should've been the choice for any tool programs instead of anything made with GTK, Qt or such c++ libraries I had used earlier. In a short time, I made some editor and tool programs with C#, which turned out to be a very productive language and potential choice even for a game scripting language. Although C# was easy to pick up and use for basic game toolset programming, there are still gaps in my knowledge about it that I'd like to fill. For example, I have familiarized myself with the concept of unit testing, but taking larger methodologies such as TDD to guide my coding process is still in progress.
This is my "C# learning project" from the summer of 2011. As I spent a lot of my free time on it during a couple of months, it evolved into a reasonably-sized project. Although not complete, it shows how I picked up C# as a tool language in 2-3 months. The project is an editor for a 2D game, and it supports a few graphics primitives. It uses Windows Forms, and XNA (DirectX 9) for its graphics (I made a custom XnaViewControl based on code from a XNA sample).
The editor was coupled with a 2D game project, but neither one finished due to the differences between the tools and the game engine. The "game engine" itself is based on DX11 graphics (editor uses XNA/DX9), and as the editor had little common code with the engine, later a branch of the engine started to evolve towards a 3D game engine instead.
Below is a 1080p video of both the editor and the game-use of the map made.
MS Visual Studio 10 project included, requires XNA 4.
If you try out the editor, note that the texture browser component is not finished.
I have made a few smaller C# tools. Below you can find two of them: a font texture generator, and a Windows Forms color styling program. These are just quick-and-dirty kind of tools, so code comments may be scarce, but the tools serve their purpose well.
This is a simple font texture generator program for my latest graphics engine projects. It renders chosen glyphs to png images, and stores the texture coordinate data for glyphs into a text file or a binary data format.
The Windows Forms color styling program, WinForms Menu Color Tool, is a WYSIWYG editor of window color styles (the window colors change in runtime). It lets you pick the colors, and generates C# class source code to create a similar color scheme for other C# Windows Forms programs.
Around 2008 or 2009 I started to take DirectX programming more seriously as well. This was mostly due to having DirectX 10 level hardware, and little knowledge of OpenGL 3. It didn't take very long until I started coding with DirectX 11 instead of DX10, since I wanted to use the new capabilities of the architecture. Knowing something about the DX11 level architecture then helped to understand OpenGL 4 as well, because there remain hardly any essential differences between DirectX and OpenGL any more. Currently I don't favor either one, and I have done programs with both.
It was also a few years ago that I started using version control tools. At first I used Subversion (SVN), but later have preferred Git, since it's simple and nice. Mostly I use local repositories, but I have a couple of them in BitBucket as well. Because of the boost in productivity and code organization, now I use version control practically for all my projects, but it is not the only change I have lately made. For some projects, I've used Doxygen to create unified comments and documentation, and even more generally my programming style has improved and become more unified, also across languages. As an example, when starting C#, I stopped using "Egyptian brackets" in favor of putting curly braces on the same level, even with other languages like C and C++. The reason was mostly the automatic C# code formatting in MS Visual Studio, but also the apparent clearness of such style.
Compiles at least with GCC/G++, a simple Makefile included.
To pass two small math courses at the university, one could create a program for making mathematical calculations. My assignment, given by the head of the department, counted some combinatorial equivalence classes of words, and the resulting program is a pretty good example of experimenting with templates and template metaprogramming (quite popular at that time). In retrospective, the code concentrated a bit too much on bit-twiddling, but the experience was also very instructive. The project featured things such as two-dimensional template recursion with large classes, which could easily explode the executable size into megabytes. The result of the program is just a set of number tables formatted in HTML, an example of which can be seen here.
In 2005, at the age of 18, entering the University of Turku to study mathematics gave me the possibility to study mathematics and physics further. Soon after that, I was skilled enough to master a lot of the mathematics required for graphics and game programming, so then I was mostly restricted by hardware, if anything. At the start of my studies, I took hardly any courses in computer science, since they seemed to have little new knowledge to offer.
For a while, the main hardware restriction was the lack of access to thoroughly use the programmable graphics pipeline. Having a cheap own computer with a lousy Radeon 9200SE, the GLSL and DirectX 9 technologies were out of reach, which ment that I had to play around with assembly language vertex and fragment programs. This turned my interest also in programming under Linux. Although I was familiar with such operating systems already from the 90s, it was until around 2005 I extensively started programming under Linux. Instead of concentrating only on game programming, I also learned a lot about making tool applications with GTK, fltk, wxwidgets and such. In the beginning, I used SDL and GTK extensions for OpenGL, but later on I ditched those in favor of using Xlib, and eventually GLFW. One important aspect of coding then was also the possibility of making a lot of OS-independent code that could run also on Windows. For some time, I actually preferred doing everything mostly on Linux just to learn the tools, such as the autotools and GNU make.
Starting from July 2006 I spent a year in the Finnish army service, which made a small gap in my studies and programming. After that I worked summers (later also weekends), which allowed me to upgrade my computer hardware as well. Then I focused on basic GLSL shaders and game engines in general. Before the army service I had already made quite large engines (around 200k in c++ code) with terrain rendering, quadtrees, custom Bender exporters (in Python), and many kind of "managers" (textures, gpu programs,...) etc, but the whole structure of the engines was still a bit loose. Instead of only learning new API-style stuff, I started having also some interest in the bigger picture of game engines. At that time, I was quite unaware of proper sources for information on the subject, but afterwards I've gotten a bit further.
My earliest graphics/game engines (from around 2005–2006) used mostly the fixed graphics pipeline functionality of OpenGL with some exceptions such as small vertex & fragment programs (asm), and simple multitexturing (detail texturing of terrain). These engines were codenamed "Maus" and "Ratte", where Maus depended on SDL libraries and Ratte did not (Ratte had actually two versions: One for Xlib, and another for win32). Below is a collection of screenshots: Maus concentrated on terrains, only the last shot here is from Ratte.
Some video of the versions I was able to recompile:
This version of the Maus engine is not the last one, but was picked only because it shows some of the functionality quite well. The engine was accompanied by a separate quad tree generator for the maps and a 3d model exporter for Blender, but these have been excluded from the package for the sake of simplicity. Soon after this version the Maus engine development actually culminated in an unfinished "flying" game ment to be made as an entry for a summer game coding competition of Suomipelit.com. Then the development suddenly almost came to a total halt, because I had to enter the compulsory military service. The Ratte engine was a follower of Maus, and its main aim was to both remove dependencies of SDL libraries and to make the engine more flexible by supporting OpenGL extensions more widely.
I've used Python mainly just to create some 3d model exporters for Blender. The examples are on a separate page.
Already around the year 2000, with new hardware at hand, I pursued my interest in 3D modeling. First, it was with not-too-legal versions of 3D Studio Max 4 and AutoCad, and later with Gmax and Blender, which I started to use around 2004. Check out examples of my later Blender work:
3d model shots page
Here you can find some pictures of 3D modeling I've done with Blender. A few shots from HL2 maps are also included, since level editing is close to the subject.
I had to wait until the beginning of the 2000s for a proper hardware update. In some sense it was advantageous, since I learned to push old hardware to its limits, but it also kept me from learning about the newest technology. In the excitement, I took a try at using DirectX 7, but I never really got far with it. The simpler and less technical API of OpenGL turned out to be easier to grasp, although the learning process was still quite slow, because I had little possibilities to learn adequate mathematics before entering Finnish lukio (after 9th grade) in 2002.
It must have been around 2003 or 2004 when I had really gotten into OpenGL programming, and understood how to use the fixed pipeline features. The main resource in the preceding years had surely been the NeHe tutorials. Graphics programming being my favourite subject, it had always given additional motivation to learn school mathematics (in which I have been very succesful), and in the time spent studying in lukio, I started to get the required mathematical skills to understand the 3d math. My OpenGL programs grew bit by bit, and eventually I made larger systems that one could call versatile 3d graphics engines (in retrospective, "game engine" would be an overstatement, since the focus was mostly on graphics).
This time also marked a keen interest in software optimization taken (from current perspective) almost to a ridiculous level. Not only by familiarizing myself with assembly language, but also by learning details of C++, I spent quite a bit of time learning many non-algorithmic or hardware-specific optimization tricks. A few good examples of the sources I had for these were the AMD processor optimization manuals, the C++ FAQ, and many flipcode articles (one favourite back then surely being "Faster vector math using templates"). It has been only later that I've understood the importance of choosing proper algorithms over nitpicky optimization by hand.
My experiments with assembly back then were limited to learning the language and its concepts, and I made only small functions and inline assembly (mostly with GCC/AT&T syntax), since assembly-level optimizations had mostly lost their importance (except for MMX/3DNow!/SSE). To get some idea, check out this example page.
Luckily (or not), a new classmate introduced me into serious coding in the 4th or 5th grade. With the help of this friend, I got the Djgpp development system & compiler with the Allegro graphics library to my computer.
Obviously, a new and more advanced language took time to learn. Basically the knowledge was provided by the local library in the format of, for example, Stephen Prata's C++ book. Fortunately the library could provide me with a few books on C and C++, and even some on more advanced subjects such as win32 programming (non-MFC). A little later on, when Internet connections became more widespread, I also got my hands on copies of Aleksi Kallio's C++ tutorial and Lamertut, both of which gave more insight into programming, as they were written in plain Finnish.
The main obstacle with C++ was still the use of graphics. Not being too familiar with the use of external graphics libraries, I frequently returned to QBasic to try out visual stuff. One of my aims was to learn how to make 3d graphics, and the basic graphics capabilities of QBasic allowed me to experiment with algorithms from the 3DICA tutorials. It was mainly during the few years before 2000 that I came aware of the techniques behind software rasterization of triangles. The matrix math associated with view projections was still out of my reach, so my own projects resorted to simple orthogonal projections or elementary trigonometric calculations for perspective projection.
My first touch to programming was around 1994 or 1993, right after my father bought the first family computer. Although I had played with other computers a bit, this ment a tremendous addition to the chances of using a computer, mainly playing games. Probably as a consequence of this, from the very beginning, my dad made a restriction that each time I went on the computer, I should make a program with QBasic before playing any games. Of course I usually managed to circumvent these programming tasks, but the times that I didn't and the example programs my dad wrote truly gave some insight into how a computer performs given commands one after another.
The greatest feature of BASIC turned out to be the ease of drawing graphics. As a very "visual" thinker, the graphical possibilities were appealing, and I actually kept QBasic as a graphical prototyping tool for many years, all the way up to the turn of millennia, when I discovered how to code with OpenGL. Before starting the use of OpenGL, I familiarized myself with both C++ and 3d graphics done entirely on software, mostly due to the fact that later the hardware in my use was very restricting.
QBasic screenshot & video page
Some of the graphical stuff is showcased on a separate page. These programs and games were made during the decade after I got my first computer.