Friday, August 14, 2015

Tracing back my steps.

Last year, I released my game The Little Plane That Could, which included an Android version. For this Android version, I had integrated leader boards and achievements via Google Play Games C++ SDK (also known as gpg-cpp-sdk). I am revisiting this SDK, as I plan to use it in my other titles as well, most prominently, for The Little Crane That Could. I did not keep too many notes during that time, so now I have to reconstruct the steps I took, doing this. This blog post is a brain dump on that matter.

NDK users, it seems, need to gather quite a few pieces from various places. One such piece is a .jar file which involves copying the directory $(ANDROID_SDK_ROOT)/extras/google/google_play_services/libproject/google-play-services_lib to your project directory.

A second piece is gpg-cpp-sdk/ which requires downloading as a .zip file from Game Services SDK Download Page. These are static libraries that you need to reference with the LOCAL_STATIC_LIBRARIES macro as 'gpg-1' in your jni/Android.mk file.

The static libraries in gpg-cpp-sdk/ only come in x86, arm, arm-v7a variants. There is no 64 bit arm variant, neither are there release notes nor a changelog.

In your AndroidManifest.xml file, inside the tag, you need to specify your app id, and the google play services version number, like so:
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<meta-data android:name="com.google.android.gms.games.APP_ID" android:value="@string/app_id" />

I based my client code on StateManager.h/cpp from a cross platform example..

On the developer portals, a lot of administration is required. This first major hurdle is that there are two different 'developer consoles' that are named similarly, but are very distinct. There is the Google Play Developer Console that manages the entire app. However, for the game services, there is another console named Google Developers Console. The latter is used to manage the use of APIs as there are: Google+ API, Google Play Game Services, Google Play Game Management, Google Cloud Pub/Sub, Drive API.

When linking your apps to the game service, you actually need to link your app twice, once for the release version, and once for the debug version. For this you need to extract SHA1 certificate fingerprints from both your release key, and your debug key. The commands to retrieve those keys are shown below. The default password on the debugkey is 'android'.

$ keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore  -list -v
$ keytool -exportcert -keystore ~/.ssh/googleplay-release-key.keystore  -list -v

I love it when I read my own stackoverflow solution to a problem I bump into a year later! You need to edit project.properties file.

Thursday, July 30, 2015

Solving quadratic equations on ARM NEON.

So two years ago, I've been coding a function that solves quadratic equations, 8 at a time using AVX. Lately, I have been looking into ARM NEON to see what performance can be had on mobile devices. This is what I came up with. The square root implementation is available pmeerw.

/*
 * solve aX^2 + bX + c = 0
 * solves 4 instances at the same time, using NEON SIMD without any branching to avoid stalls.
 * returns two solutions per equation in root0 and root1.
 * returns FLT_UNDF if there is no solution due to discriminant being negative.
 * For sqrtv() see: https://pmeerw.net/blog/programming/neon1.html
 * I've put the reciprocal of (2*a) in the argument list as this one is fixed in my particular problem.
 */

inline void evaluate_quadratic4
(
        float32x4_t a,
        float32x4_t twoa_recip,
        float32x4_t b,
        float32x4_t c,
        float32x4_t* __restrict root0,
        float32x4_t* __restrict root1
)
{
        const float32x4_t four4 = vdupq_n_f32( 4.0f );
        const float32x4_t undf4 = vdupq_n_f32( FLT_UNDF );
        const float32x4_t minb = vnegq_f32( b );                        // -b
        const float32x4_t bb = vmulq_f32( b, b );                       // b*b
        const float32x4_t foura = vmulq_f32( four4, a );                // 4*a
        const float32x4_t fourac = vmulq_f32( foura, c );               // 4*a*c
        const float32x4_t det = vsubq_f32( bb, fourac );                // b*b - 4*a*c
        // We want only positive roots!
        const uint32x4_t  dvalid = vcleq_f32( fourac, bb );
        const float32x4_t sr = sqrtv( det );                            // approximation of sqrt( b*b - 4*a*c )
        float32x4_t r0 = vaddq_f32( minb, sr );                         // -b + sqrt( b*b - 4*a*c )
        float32x4_t r1 = vsubq_f32( minb, sr );                         // -b - sqrt( b*b - 4*a*c )
        r0 = vmulq_f32( r0, twoa_recip );                               // ( -b + sqrt( b*b - 4*a*c ) ) / (2*a)
        r1 = vmulq_f32( r1, twoa_recip );                               // ( -b - sqrt( b*b - 4*a*c ) ) / (2*a)
        // Filter out negative roots.
        *root0 = vbslq_f32( dvalid, r0, undf4 );
        *root1 = vbslq_f32( dvalid, r1, undf4 );
}

I benched this code on Android Galaxy Note4, against a scalar version. The speed-up I measured was 3.7X which I think is pretty good.

So, yeah, writing intrinsics is totally justified. Doubly so, because I tried to have the compiler auto vectorize, but whatever flag I tried, results hardly differed: -fno-vectorize, -ftree-vectorize and -fslp-vectorize-aggressive all showed the same performance.

Wednesday, July 29, 2015

ARM SIMD

My Pyramid Building Simulator is coming along nicely. Check out the game play video I made for it.

So my Core i5-4570 and nVidia GTX 750Ti run this simulation at an easy 100fps at 1920x1200 pixels. It always leaves me wondering, could it possibly ever be done on mobile, 64 bit iOS or 64 bit Android? If it's possible, it will require some aggressive optimization, as the current code is already AVX SIMD.

But it's an itch I have to scratch: can I do the same on 64 bit ARM NEON? So let's dive into that world: I've never done assembly, intrinsics or SIMD on ARM before, so it's all new to me. I've found a developer that went an interesting route: translate x86 SSE2 to ARM Neon using a translation layer. But I think it pays more to apply ARM Neon intrinsics directly.

So what have I been able to find out so far?

  • This ARM intrinsic reference is a great resource.
  • An old blog post at hilbert-space.de warns against intrinsics being much slower than hand written assembly. I believe this is currently no longer true, as compilers have matured, and this was mainly an issue with older gcc compilers.
  • ARM does have the notion of 16 bit floats, but unfortunately, it seems to be a storage format only, and not suitable for calculations. This is a pity, as it seems to rule out 8-way floating point SIMD on ARM. I may be mistaken, but it looks like you can't do better than 4-way floating point SIMD on ARM, which is a far cry from the x86 world where 8xSIMD (AVX/AVX2) and 16xSIMD (AVX-512) is possible.
  • NEON Intrinsics look like vXXXq_FMT where v signifies the vector nature, q means 128 bits, and FMT specifies integer/float and width. So for instance: vmulq_f32() that multiplies 128 bit vectors containing 32 bit floats, so this would be 4xSIMD.
  • For conditional moving of values (which in x86 parlance is vblendps or fsel in PowerPC speak) you would use Bitwise Select, vbslq, in the ARM Neon world. In NEON, this intrinsic is actually much more natural than the x86 counterpart, as it has a more logical operand ordering. It follows the same ordering as the ?: operator in C: vbslq( condition, iftrue, iffalse ).
  • Writing NEON intrinsics is actually quite enjoyable compared to the x86 world, where MMX, SSE, SSE2, SSE3, SSE4, AVX, AVX2, AVX-512 transitions left the set of intrinsics quite convoluted. The naming scheme in ARM NEON is much cleaner, and requires less use of references as it contains little surprises in naming. The comparison intrinsics are also easier, as there is no third operand as is the case in x86. The type of condition is specified in the name of the intrinsic instead.
  • Ugh, NEON doesn't have square root, or reciprocals. Only an estimate for reciprocal, and an estimate for reciprocal of square root. It looks like pmeerw has a solution to this.

I will update this posting as I learn more about ARM SIMD.

Tuesday, July 14, 2015

Hieroglyphic User Interface.

So, I have embarked on a new game project: A pyramid building simulator. And I decided to go hard-core on authenticity and do all of the UI in hieroglyphics. I've familiarized my self with the script, and the Gardiner classification.

And in Inkscape, I've created a set of words from Ancient Egypt, with the help of this tool among others. Here are the words for: Baker, builder, field, fieldworker, food, grain, granary, house, householdservant, irrigationworker, pyramid, sandstone, water, which are all elements in my new game, and will require UI.

As can be seen from the orientation of the birds and the men, these are reading-right-to-left variants. Stay tuned for some upcoming game play videos that will appear here. If you are press and would like advanced copies of the game, please do no hesitate to contact me.














Tuesday, June 30, 2015

Approximate functions.

For game development, I often use function from the math library, as there are: sinf(), cosf(), atan2f(), acosf(), logf() and such. And these functions tend to be quite expensive in CPU cycles. However, in game development, low precision math functions will often suffice. Which means we can skip computing a precise answer, and use other functions that approximate the output of the expensive functions.

I've found a few resources for code that approximates expensive math functions with much cheaper approximations. There is SIMD Math prims by jhjourdan e.g. that comes with approximations for expf(), logf(), cosf() and sinf(). As a bonus, these simpler functions are also easier to vectorize.

But my favourite approximation is that of atan2f(), because I use it so often to convert direction vectors to angles. Here are Volkan Salma's approximations for the atan2f() function.

Monday, June 22, 2015

Tile sets

My next game could well be a 2D tile based game. This is mainly, because I want to use my 2D grid based crowd simulation code. So here I will collect some inspiring art work I found with Google. Note: none of the images are mine, they are all copyrighted by their respective authors. I'm just scrap-booking here to see what art work is out there.

An interesting variant of tiles on a 2D grid, is the use of a height-map, so that there are still NxM tiles on a grid, but each tile has a height. The advantage of doing this over free 3D, is that the navigation on a heightmap is still a 2D affair.











Monday, April 27, 2015

Friday, April 17, 2015

Steaming Ahead - WEEK 09

Yay! The Little Crane That Could -- steam edition is finished! So today, I submitted my game for review, and if it gets through, it will be out on April 27.

I also made this launch trailer:

I'm excited for its release. I've worked very hard for 9 weeks after I got the Steam green-light. And now it is here! I will reward myself with some Scottish Whisky tonight.

At launch you will be able to grab your Win/Mac/Linux copies at 15% discount. And last, let me phrase why this game stands out, and is unique among its peers:

The terrain is the real hero in this game! With never seen before dig-anywhere technology™ you can shape the world. Any changes to the world will persist between levels and game sessions, and there are no restrictions: cliffs, overhangs, caves, tunnels: it is all possible.

The world size is near infinite: you can dig a hole, then drive for an hour in a random direction and backtrack by following your track impressions in the terrain. You will then find your dug hole as you left it: no short-cuts: real terrain simulation!

One disclaimer: I did not solve the problem of 'floating terrain' though... dig away all the dirt below and round an area, and the remaining dirt will float mid-air. I think it has limited effect on enjoyment and playability though, and as it is far from trivial to fix, I will leave it at this."

Saturday, April 11, 2015

Steaming Ahead - WEEK 08

The eighth week of work since I got Steam Green-lighted has come and gone. So as promised, here is a weekly update on the progress towards the Steam release of The Little Crane That Could.

I have done most of the Steam API integration, and tested this on Windows and Mac builds. The integration went reasonably well, so there may be a simultaneous release for multiple platforms. I did notice some issues of the steam overlay on OSX with retina display though. I have added Steam statistics and achievements as well. Because I use the steam folder for game storage, I intend to lock the game to steam. This means that it will not run if the steam client is not running.

I have added fog to the game so that the popping in/out of terrain geometry is less glaring. You can still easily see it, but it is less prominent now. The fog also adds a depth-cue. And I added a simple sky gradient from white at the horizon to blue overhead. So the visuals are still far far away from cutting edge, but at least they look a little better now. This game's strength is the state of the art simulation code, not its pretty looks.

I also added reconfigurable keyboard control, where you can assign keys to the functions in a .txt file. And to help, cheat-sheets for keyboard control and gamepad control are added.

Friday, April 3, 2015

Steaming Ahead - WEEK 07

The seventh week of work since I got Steam Green-lit has come and gone. So as promised, here is a weekly update on the progress towards the Steam release of The Little Crane That Could.

Some good news: Again, I added two new levels this week, bringing the total to eight levels, which I think is enough for a first release of the game. I particularly like the last level, in which the Crane and the Bulldozer need to work together as a team. I think the veteran players of the mobile game will like how it turned out. I also made a big leap in quality for the simulation of the excavator. The bucket now interacts with the terrain a lot better.

Because some good strides have been made towards release, I now need to spend time on non-engineering tasks. I started to create a store-front for on Steam, and getting the artwork in place. For what is called the 'box-shot' I turned to what is my favorite rendering tool: Kerkythea. This renderer has good support by Wings3D, so I can setup the scene, and the camera in Wings3D, and have Kerkythea do a great photon-mapped rendering of it. Let me know what you think of it in the comments!

I tend to do most development on Ubuntu, with an occasional jump to OSX if I need to do profiling. But now I switched to using Visual Studio more, and have been dusting off the Microsoft Windows port. All this in preparation for the steam release of course, where Windows is the most important platform. For next week, I will work on integrating Steam's API into the game. I have already started reading the documentation on it.

Friday, March 27, 2015

Steaming Ahead - WEEK 06

The sixth week of work since I got Steam Green-lighted has come and gone. So as promised, here is a weekly update on the progress towards the Steam release of The Little Crane That Could.

This week I added two new levels, bringing the total level count to six. Both levels involve operating the crane, as opposed to a bulldozer or excavator. I also created a truck for hauling cargo. And I've spent a lot of time tweaking the soil simulation. For instance, merging back the soil particles in the terrain has been improved, so that the resulting terrain is smoother, with less hard edges. The quality of the soil simulation is getting close, but is still not ready for release.

A lot of work remains to be done. I want to release with a minimum of 8 levels, so I need to create at least two more. I need to look into the Stream SDK, and integrate it into my game. I need to create a convincing sound for the pickup truck, as currently it sounds like a diesel bus from London. And there are a lot of other loose ends to be tied up.

Friday, March 20, 2015

Steaming Ahead - WEEK 05

The fifth week of work after the Steam Green-lighting has come and gone. So as promised, here is a weekly update on the progress towards the Steam release of The Little Crane That Could.

I have added two new levels for the bulldozer. In the first level, you need to clear a helipad covered by a landslide. I especially like how this one turned out. I also added a level where you recover a stranded truck with the bulldozer. That one is a little less refined.

A added a cheat-sheet graphic that shows the controller mapping. It displays dynamic information, which changes as you switch vehicles, or switch modes from driving to camera to hydraulics. It's not pretty, but it is effective. I don't have controls remapping yet. I fear that may be a hairy one. I will have to see what the steam sdk expects for this.

Lastly, I have been tuning the excavator physics, so that it will properly scrape dirt from the terrain using its bucket. Oh, and as a bonus: I've finally switched my shading from Gouraud to Phong.

Friday, March 13, 2015

Steaming Ahead - WEEK 04

The fourth week of work after the Steam Green-lighting has come and gone. So as promised, here is a weekly update on the progress towards the Steam release of The Little Crane That Could.

I have added a level selection screen to the game, using my Dutch-Blunt vector font. Like the font, the screen is very minimalistic, see below.

I have created the first level for the game, which is a simple driving exercise where you need to follow a parcours trough the hills. Here's a map of the current parcours.

I have added a game-over screen that gets triggered when you win or lose a level. And then I also added a second level as well, which is an exercise in loading cargo.

I spent quite a lot of time getting a topographic map in the game. But I am pleased with the results.

Saturday, March 7, 2015

Steaming Ahead - WEEK 03

The third week of work after the Steam Green-lighting has come and gone. So as promised, here is a weekly update on the progress towards the Steam release of The Little Crane That Could.

This week I started to think about actual level design, and what missions to assign to the crane/bulldozer/excavator/whathaveyou. And I am also having second thoughts about the title 'The Little Crane That Could'. The new engine's main feature is the soil-simulation, could it be that the bulldozer and digger will be more prominently feature in the game that the crane?

  • The Little Diggers That Could?
  • The Little Dozer That Could?
  • The Little Machine That Could?
  • Mud Machines?
  • The Little Crane That Could II?
Frankly, I don't know any more. The steamworks interface lets me rename the game, but it could very well be that this renaming is a one-chance only, so I need to get it right.

So back to the level design... I think that after a driving tutorial, the first mission will be a loading task, where the crane truck will load a pickup truck. So first order of business was putting a pick-up in the game. I decided on using this pickup model from turbo squid. It took me a day to reduce the vertex count of the model so that it was suitable for in-game use, and then I had to rig up the physics for it. I think it looks pretty good, but still needs better audio, because I am still using a very low-revving big old diesel engine sound for all the trucks. It is fine for bulldozers, excavators and big rigs, but for a pickup truck not so much.

With the pickup truck added to the world, I then had to put in a mechanism to switch between vehicles. So first you operate the crane truck so that you can load the pickup truck. Then with the TAB key, you switch controls to the pickup truck so that you can drive around with your freshly loaded cargo.

And lastly, I've been distracted with the design of a new font to be used in my games. I created a low poly font called Dutch-Blunt and I open sourced it.

Friday, February 27, 2015

Steaming Ahead - WEEK 02

The Second week of work after the Steam Green-lighting has come and gone. So as promised, here is a weekly update on the progress towards the Steam release of The Little Crane That Could.

I'm not going to lie: this was a week of frustration. Source of the frustration was a wild goose chase to fix a shadow mapping bug. As a detour, I thought a windows port could help me solve this bug, with some OpenGL debugger tools from AMD, e.g.

So the sub-goal for the week was a windows port. So far I have been developing under GNU/Linux, and occasionally using the Mac OSX port. There are a lot of things missing in the windows world. One of them is pthreads. Fortunately, SDL includes support for platform independent threading, so I rewrote my pthread code to SDL_Thread code, which has a similar API. I am seeing really bad performance on windows though, and I am not sure what the cause of this is. It could be that SDL threads are slower than pthreads. This needs more investigation.

Other missing functionality in windows world is opendir(3), which I worked around with a temporary hack.

So did anything gameplay-related happen this week? Well, at least I can now read in modular level designs, that were created with my Little Crane World Editor. So at the very least I can build things like parking lots, or spawning-platforms, so that not everything in the world is muddy hills.

Friday, February 20, 2015

Steaming Ahead - WEEK 01

The first week of work after the Steam Green-lighting has come and gone. So as promised, here is a weekly update on the progress towards the Steam release of The Little Crane That Could.

I've spent this week on actually building a crane vehicle. The code base so far only contained a bulldozer/loader and an excavator. And now, there is an actual crane as well. The crane turret and cabin are from a model purchased at TurboSquid. The truck underneath, I modelled myself in Wings3D.

However, most of the time was spent on doing the physics sim for the truck and the crane. I'm pleased with the truck, that now has 4 axles instead of 2, and all driven. The wheel suspension is softer than the old crane I used in the mobile version of the game, and they look great. It took quite some time to get the sim stable without too much jitter, but the quality is now pretty close to shippable. So without further ado, shown below is what the new Little Crane looks like.

For next week, I want to see if I can get some actual game-play back in, probably in the form of the old basket-ball level from the mobile game version. I hope you'll follow me again in next week's progress report. Until then, I will leave you with this great shot of the truck's suspension.

Sunday, February 15, 2015

Steaming Ahead - WEEK 00

Such great news, Friday 13th of February 2015: The Little Crane That Could has been green-lit, meaning my game will be published on the Steam store. Yesterday I announced that I pledge to, EACH AND EVERY WEEK, publish a progress report on my steam publication.

So without further ado, here is report 00, where I will report on the current state of the project.

There are two code bases relevant to this steam publication. There is the unified code base that is used to build the iOS, Mac, Linux, Win, Android, OUYA, GearVR versions of the game. This is what I call the Legacy Code Base (LCB). Next, there is a new code base where I have researched soil simulation, with real time terrain deformations. I will call this the Research Code Base, or RCB. The steam build will be making use of the RCB, to make it a fresh new game, with some amazing technology behind it.

Currently the RCB is a capable engine with the following features:

  • Soil simulation where terrain can be scooped up, and deposited anywhere. It is a true isosurface capable of caves, overhangs and such, so is not limited to a simple height field.
  • Supports an infinitely large procedural world. Only changes made to the terrain are stored to disk.
  • Features a bulldozer simulation.
  • Features an excavator simulation.
  • Diesel-engine sound effect.
  • Caterpillar track simulation that leaves depressions in the terrain.

The most notable omissions in the RCB include:
  • Lack of integration with steam.
  • Lack of levels, goals, gameplay.
  • No crane vehicle simulation.
In the months ahead, I intend to address the crane simulation first, and will read up on steam publishing. There are some decisions to be made regarding publication, as there are:
  • Will I do Steam Early Access? I'm leaning towards yes, but gameplay needs to be in place for this.
  • Will I adopt any steam specific technology, as there are steam trading cards, steam big picture, etc?
  • How many game levels will be part of the first release? And how much overlap with levels in the mobile game will it have?
Tune in next week to see what progress has been made. And let me leave you with the current vehicles from the RCB.

Here is a video of the excavator in action, and one of the dozer in action.

Thursday, January 29, 2015

Accelerating GI computations.

So I have been developing a new game where a rocket engine Globally Illuminates its environment. It started out as an AVX2 implementation, but since then I have been pursuing other acceleration techniques. For instance, can I run the photon mapping algorithm on the GPU instead? Here are some initial results of the different approaches.

Technology: AVX2, single threaded.
OS: Linux
Device: i5-4570 CPU @ 3.20GHz.
Cores: 1
Frames per second: 51

Technology: GLSL- OpenGL3.2
OS: Linux
Device: Intel® HD Graphics 4600 GPU
Cores: ?
Frames per second: 37

Technology: GLSL- OpenGL3.2
OS: Linux
Device: ATI HD 5670 Graphics, Open Source Gallium driver.
Cores: ?
Frames per second: 60

Technology: OpenCL 1.2
OS: Linux
Device: i5-4570 CPU @ 3.20GHz.
Cores: 4
Frames per second: 38

Technology: GLSL - OpenGLES 3.0
OS: Android
Device: Adreno(TM) 420
Cores: ?
Frames per second: 10-14.
Remarks: Oscillates with a 3.5s period. Thermal throttle?

Technology: OpenCL 1.2
OS: Mac OSX
Device: i5-4278U CPU @ 2.60GHz.
Cores: 4
Frames per second: 11
Remarks: Could not handle work group sizes larger than 1.

Technology: OpenCL 1.2
OS: Mac OSX
Device: Intel Iris GPU
Cores: 40
Frames per second:-
Remarks: Apple's OpenCL compiler failed to build the OpenCL kernel source. Gave 'Parse Error' on a perfectly fine source fragment for no traceable reason.

Some conclusions I got from this: OpenCL has not been worth the effort. It takes 4 CPU cores to get to a speed that still lies significantly below the speed of my hand optimized AVX2 implementation that runs on a single core.

Apple's OpenCL seems to be in a bad shape. I could not get it to run on GPU, and running on CPU yielded a 3.5 times slower result compared to Linux.

The GLSL implementation seems promising. A dependency on ES3.1 or OpenGL 3.2 is less of a barrier than the AVX2 dependency. With some temporal caching, and reducing photon counts, it should be able to reach solid 60fps on integrated GPUs, and maybe even 60fps on future mobile CPUs.

Saturday, January 24, 2015

Programming

Programming is my passion. It is the best life-time hobby I can imagine. It all got sparked in 1982 when I played Munchkin on a friend's Videopac G7000. This pacman clone blew me away, and I desperately wanted a 'game computer'. My father replied to my plea: `No we are not going to buy a game computer. We'll buy a real computer.' To which I replied: `What is a real computer?' The answer hit like a bomb: `With a real computer you can make your own games.' The rest, as the saying goes, is history. Here's an overview of the programming languages in my life in rough chronological order.

  • It all started with ZX Spectrum Basic.
  • Then Z80 machine language (Assembler came later!)
  • Forth, using White Lightning from Oasis Software required a mental shift due to the RPN.
  • Intel 8086 assembly.
Most of the programming languages I picked up were studied as part of my Computer Science degree at the University of Amsterdam:
  • Pascal
  • Motorola 68K assembly
  • Microcode
  • Scheme
  • Sasl
  • Fortran
  • Prolog
  • C
  • Occam
And then in mostly in industry, I picked up:
  • Postscript (stack based like Forth)
  • C++
  • Python
  • Objective C

Currently, my favourites are C (I use a C++ compiler but try to use as little C++ features as possible) and Python.

Wednesday, January 21, 2015

Extraterrestrial spelæology

So my Global Illumination experiment made some more progress. The technology demo is slowly evolving into an actual game. And the hero of this game might very well be a spelunking rocket. Maybe I should call the game Spelunking Rocket? It currently has a single Google hit, so it should be easy to find online.

So what you see in the video is a rocket flying through a voxel world that is defined by a 3-octave simplex noise function. I sample one noise field to determine block/empty space, and sample another noise field to determine the hue. Notice how the rocket exhaust illuminates the scenery, both directly and indirectly via light bouncing off a wall. Also, the exhaust particles collide with the world, and act as light sources for my photon mapper.

In the left corner an instrument that combines attitude-indication (where is the rocket's nose pointing?) with a compass. Flying towards the little circle on the perimeter will make you go in the +X direction, where the first coordinate increases. The attitude indicator helps you to right the rocket, although there is also an autopilot function mapped on the gamepad that does this automatically using PID controllers.

Still to do are game play objectives. I was considering putting fuel drops in the world, and make them more rare as you move further away from launch position. Farthest voyage wins the leader board?

For technical challenges, there is still the issue of moving away from AVX2 which is not widely supported on current hardware. A possibility would be doing GPGPU. Possible APIs are OpenCL, OpenGL4.3 Compute Shaders, CUDA, Apple Metal. CUDA is too proprietary, as is Metal. OpenGL4.3 support is horrible: I don't think a single Macintosh can do this?

Sunday, January 11, 2015

Rocket Engine Illumination

So I have been playing with my real time Global Illumination renderer some more. I added a particle system to model a rocket engine. The particle system is comprised of 1024 particles. And the kicker is: each and every particle is a light source that casts both direct and indirect light. For each particle, 24 photons are fired in random directions. When a photon hits a surface, a secondary photon is emitted in a diffusely reflected direction. This bounced photon creates the indirect illumination. See for instance the red and green glows that are created if the engine is close to a coloured wall.

In the video, the best demonstration of indirect light happens as very short flashes of green and red on the sides of the center block. If the engine flame is directly above the center block, its light cannot directly reach the sides. So mainly the light bouncing off the coloured walls reaches the sides, causing them to briefly flash in green or red before going bright white as the engine light shines directly upon it.

It currently runs 60fps on a single Haswell core. But I plan on multi threading the code so that I can increase the photon count. This should reduce the light flicker. The code is in AVX2 intrinsics, so it's rather incompatible with most PCs. I may have to port it to AVX or SSE at some point in time.

Next up in my GI research is integration into an actual game, preferably with rockets of course. I feel like making a GI homage to the ZX Spectrum classic JetPac.

Sunday, January 4, 2015

Moving lights

So my Global Illumination Voxel Engine Research is making progress. I've added colour, indirect lighting, and also SIMD intersection tests. The SIMD is AVX 8-wide. And the speed up compared to scalar code is 4.5x which leads me to believe there is some room left in optimizing it. It now runs 38fps on a single 3.2GHz Haswell core.

Notice the low-frequency noise. Photon Mappers typically have high frequency noise, and path tracers that update only some of the screen's pixels have even higher frequency noise. The noise in my renderer is much more pleasant, and reminds me more of oscillating electrical lighting, or maybe the flickering of a fireplace flame.

Friday, January 2, 2015

2014 totals

So, The Little Crane That Could is still chugging along, but undeniably it has peaked. I hope there is life left in the brave little crane, but it may be running out of steam. Here are the 2014 results (Number of free Downloads.)

2014 2013 2012 2011
iOS 1300K 3199K 3454K 1550K
Android 825K 1579K 1656K -
Mac 30K 53K 81K -
OUYA 4K 15K - -
Kindle 46K 95K - -
Rasp Pi ? 6K - -

I have been unable to check the Raspberry Pi downloads. The statistics report on the raspberry store is broken. It looks like the pi store was part of indiecity, which is part of Blitz Games, which seems to have gone under. I'm not sure if the download is still available on the store.

This brings the grand total of Little Crane downloads to 13.9 Million. Hooray for Little Crane! One last note: Little Crane is also available for GNU/Linux and Windows, but those releases saw downloads in homeopatic doses.

Thursday, January 1, 2015

More Photon Mapping

In yesterday's post, I introduced my new hobby project Photon Mapping Voxels. Today, I made some more progress, and managed to properly interpolate the shading. The voxel faces in a plane now share vertices. But there is still a matter of ambiguity when shading a quad, which causes the triangle seam to show in the middle of the quad. To alleviate this issue, I added a center vertex in the middle of the quad, and render it as 4 triangles, instead of just 2. The results are below. The animated gif cycles through four renderings: quads, triangles, triangles in wireframe, quads in wireframe. As you can see, there are less discontinuities in the triangle version, at the cost of more vertices, and double the triangles.

Again, this is direct light only. I am getting excited about seeing it with indirect light (bounces) and also colour. Currently, all photons and all voxels are white. Also on the todo list: make it really fast by doing SIMD intersection tests: a ray versus 8 voxels in a single go. This requires AVX though, probably AVX2 even.