« Posts under Games

Trip Report: Gamefest 2011 – Seattle

I managed make it out to Seattle this year for Gamefest and figured I’d share my thoughts on some of the different presentations I saw. They are not available yet, but it looks like Microsoft is going to be posting the slides/audio for the different presentations here soon.

Tiled Resources for Xbox 360 and Direct3D 11 – Matt Lee

This talk was about mega-texturing in DirectX 11/Xbox 360.  Matt Lee was showing a new DirectX SDK sample that’s coming in the next SDK release giving a reference implementation of a mega-texturing run-time.  I’ve only skimmed mega-texturing papers so I got a lot out of this talk since he walked through all the steps in the run-time.

The sample shows off how you begin by creating different tiles for different resource formats.  Each pool is dedicated to a different texture format.  The tiles in the pool are all the same size; However the tiles may vary in size depending upon the texture format to maximize cache efficiency.  When you render the scene you have a shader that can write out texture look-up failures.  When the UV coordinates and mip level are not found to be resident in memory a failure is added to this list.  After the shader completes you read back the failures and proceed to load the tiles that will fit in your established pools.

Unlike most texture streaming systems you’re not loading an entire mip level or the entire mip chain of the texture.  You’re only ever loading into the tiles a sub-region of a texture (like a 64×64 pixel region), which overcomes one common texture streaming problem, texture memory fragmentation.  Because the tile pools you create are never deallocated you don’t have to worry about fragmenting your texture memory because of different sized textures being streamed in and out.

Now the sample is not without its short comings, but that is mostly due to hardware limitations.  Ideally the virtual texture system would be transparent, you wouldn’t need to write a shader that recorded look-up failures.  The GPU and DirectX would simply report when a failure occurred and allow you to handle it.  Maybe some day…

Gesture Detection Using Machine Learning – Claude Marais

If you have ever been interested in machine learning this is a worthwhile presentation to check out when the slides are posted.  Claude Marais talked about a case study they performed to try and use machine learning to detect a Punch and a Kick.  For their experiment they used Adaboost which is a machine learning technique that combines thousands of weak classifiers that ‘boost’ each other and provide you with a high degree of accuracy in the results.

The classifiers are all extremely simple things, for example you may have a classifier like:

C++
if (elbow_joint_angle > ANGLE)
    return 1;
return -1;

Then simply create a macro and have 180 variants of this classifier one for each ANGLE.  If you can imagine all the different things you could measure about the skeleton, creating simple variants of the kernels for each of the possible test cases will explode the number of weak classifiers you have; Claude had around 21,000 weak classifiers for his system.

The training phase looks at labeled data sets to know what examples of punches look like (positive examples) and what -not- punches look like (negative examples).  It uses the +1/-1 scores each weak classifier provides to determine the weights to apply to each classifier.  After it has determined the best weak classifiers to detect a punch and not detect a negative example as a punch on accident you can use the classifiers at run-time with the weights applied to detect a punch.

The results were undeniable; they had a demo setup the the expo area that was really good at detecting a punch and kick.

The only real drawback to this solution is the data collection; they needed something on the order of 70,000 examples of punches and 7x that in negative not a punch examples before the training produced accuracies over 90-95% from the chart they had; if my memory is correct.

In training the system they had 70,000 frames worth of recorded training data.  The actual number of recorded punches used to train the system was 25 different people doing 10 punches, so around 250 punch examples.  Then they had about 7x that number in negative training examples, which might be things like waves, or other actions that SVM can use to differentiate between random movement and an intentional punch. (Thanks to Claude for clarifying this)

Kinect and Kids: Pitfalls and Pleasantries – Deborah Hendersen

If you had asked me to make a Kinect game for kids (ages 3-6) before seeing this presentation I likely would’ve designed something with a dumb-me as the target audience.  What I quickly realized is how wrong I would’ve been to make that assumption.  At that stage of development kids are not capable of interacting with games I’m used to playing.

Something as simple as a menu of options is an impossibility since they are illiterate.  How many games have you seen that you could play without knowing how to read?

When interacting with an onscreen character, the kids ignore social norms of waiting for the person to finish talking.  They may just jump the gun if they already know what is expected and get frustrated if they can’t do it when they want to.

Kids are distracted very easily and will make their own games out of game behavior.  Deborah mentioned one story where a kid stopped playing the game because he realized he could get the game to react to leaving the play area and Kinect could no longer detect him the game would do something.  So he made up his own game of jumping in and out of the play area to activate this condition; utterly boring for adults, completely entertaining for this kid.

You almost have to design the game like passive experience like a children’s TV show.  Where on TV because there is no feedback, the TV show host asks the kid, “Can you find _______?” and the kid at home says something, and expecting this the show simply pauses while he waits for the response.  The game has to function in essentially the same way, regardless of the kid participating in the expected fashion the game has to move forward.  If it functions like a state machine that requires proper actions to move forward the kid may become bored and simply want to move on.  If the game refuses to let them move on, they’ll just walk away.

I really enjoyed this presentation because it was very clear how difficult the problem space is and it was interesting to hear how they tried to solve each one.

Kinect Hands: Finger Tracking and Voxel UI - Abdulwajid Mohamed and Tony Ambrus

This presentation was broken into two completely different parts, the first part was on finger tracking with Kinect.  This is one area I’ve been playing around in for awhile so it was interesting to see someone else’s attempt to solve the problem.  Because the Kinect is a structured light depth camera you don’t necessarily have depth at each pixel like you would on a time of flight depth camera.  Structured light cameras build a topology of depth using the light pattern it projects into the scene, viewed from a different angle it can discern depth, but a single dot does not give you depth.  It connects groups of them when determining the depth of a surface.  This means that even though your hand can be seen by Kinect, the further you back away from the sensor, the more like a mitten your hand becomes.  The gaps between your fingers disappear until they are just clumps on your wrist.

Because of this limitation you can’t go past 10 feet, there simply isn’t enough data.  Ideally the user is at 6 feet or closer, past 6 feet the accuracy begins to break down.

The way Microsoft tackled the problem was to first capture lots of hand examples and then to train an SVM (Support Vector Machine) against a curvature analysis of the hands.  So once you know all the pixels that make up a persons hand you find the points on the hand that result in the largest changes in curvature.  On an open hand these curves are your fingers and if you’re close enough to the camera that it can see the gaps between fingers it’s a very large change in curvature.  A closed hand has more or less a uniform curvature change viewed from any angle.  By training the SVM against a set of closed hand curvature examples vs. open hand curvature examples they were able to get pretty accurate results at about the 6-8 foot range for an adult, 5-7 feet for kids.

Because the detector is instantaneous i.e. it can tell you in a single frame is the hand open or closed, you need some something to counteract a single/couple misinterpreted frame.  So they trained an HMM (Hidden Markov Model) on examples of a flaky transition where the system is quickly switching between 2 states because the hand is at an odd orientation confusing the SVM; I thought it was an interesting solution to the problem.  I’ve only ever tried something simple like requiring 3 contiguous frames of agreement to have a state change.

The second half of the presentation was on a 3D (not stereoscopic) UI for Kinect.  One of the problems with navigating a ‘push to click’ interface is that it’s hard to correct for user drift.  When a user pushes forward they may do several things,

  • Push toward the TV
  • Push toward the sensor
  • Push forward (wherever forward happens to be at that moment in time)

Depending upon what you’re expecting them to do there’s going to be drift away from the thing on the screen they are trying to click.  To attempt to correct this Abdulwajid presented a UI where the hands are visualized as voxelized clumps of boxes in a 3D environment with 3D buttons that could be mashed.  Seeing the hand in the same space as the button appeared to make it much easier to perform the click.

One thing I noticed that was not called out was his use of 2 directional shadow casting lights.  By having 2 directional lights facing each other both casting shadows, the resulting effect is a focal point.  As the hand gets closer to a surface the eye perceives the two shadows heading towards each other and can see the point where they will meet.  I thought that was and additional powerful indicator of where your hand was moving in the space and made it much easier to correct drift.

Terraria: The Auto-Saving Server

After beating Minecraft (not really) I thought my addition to these blasted sandbox mining games was satisfied.  Sadly, I was wrong.  I started playing Terraria a few days ago and its got many more game elements than Minecraft.  It’s also wildly addicting if you’ve got a sever case of ‘Got’a’ Catch’em Alls’.  It’s also possibly the real world equivalent of Heroin Hero.

In any event, I setup a server for my friends and I to play only to discover that the server does not auto-save the world.  So if it crashes or is shutdown improperly, everything in the world resets.

So I wrote a little bit of code to fix it and decided to share.  It’s a simple bootstrapping program, you give it the file path of the Terraria server executable as the first argument and then all the other arguments to pass to it as a single string.  It then sends save commands to the server every 10 minutes.

If you want to just download a compiled version for yourself, you can download it here.

If you were to place it in the same directory as the TerrariaServer, you’d run it like this:

Text
TerrariaAutosave.exe TerrariaServer.exe "-config serverconfig.txt"

P.S. You never catch the dragon.

Hierarchical Z-Buffer Occlusion Culling – Generating Occlusion Volumes

volume_cat

Almost a year ago I wrote a couple of posts on Hierarchical Z-Buffer Occlusion Culling (HZB-OC).

One very glaring issue I left largely untouched was the workflow issue.  Artists currently have to author all or a large percentage of the volumes by hand in the implementations I’m aware exist.  Ideally these simplified occlusion volumes would be generated by a tool in the art pipeline instead.

A few weeks ago I started looking for a new side project and decided to try and flesh-out a very rough idea I had for automatically generating occlusion volumes.  This is still a work in progress but I wanted to share my current progress because I think it has some value even at this early stage.

The Problem

An ideal occlusion volume has some important features,

  1. Conservativeness – Doesn’t extend beyond the surface of the mesh
  2. Simplicity – The occlusion volume is made of very few triangles or is fast to render
  3. Volume Conservation – Closely matches the original mesh’s volume
  4. Dynamic – Some games have large movable occluders or destroyable walls

Normal methods of simplifying a mesh such as typical triangle simplification causes problems in both the area of conservativeness and volume conservation.  In some cases you can use the physics collision mesh if available.  One thing to be aware of is that when the physics volume is larger than the visual mesh it can cause false occlusions leading to things popping into view.  Also not every mesh needs a physics volume nor are physics volumes always meshes.  Will Vale’s talk from GDC 2011 covered using physics collision meshes pretty thoroughly for HZB-OC, you should check it out.

The Technique

Let me start by summarizing the technique I’ve been developing for generating the occlusion volumes before I go in-depth into each step in the process.

  1. Find all the voxels completely inside a mesh
  2. Find the voxel at the densest point in the volume
  3. Expand a box from this point until all sides collide with the mesh surface or another box
  4. Repeat 2-3 until you’ve consumed X% of the total volume
  5. Filter small or useless boxes (Unimplemented)
  6. Use a Constructive Solid Geometry (CSG) algorithm to merge the boxes you create

1. Voxelization

surface_solidFirst you have to determine all the voxels completely inside the mesh.  That way we can have complete confidence that anything we generate contained inside these voxels will be conservative.  It also gives us a very easy way of quantifying the total volume and the volume remaining.

The voxelization algorithms I ended up using comes from this paper Fast Parallel Surface and Solid Voxelization on GPUs [Schwarz 2010].  I used the 3.1 section for surface voxelization and the 4.1 section for solid voxelization.  Both are required because a voxel is considered part of the solid volume if the center of the voxel is inside the mesh.  We want the entire voxel to be inside the mesh though.  So you have to remove the excess voxels from the solid set using the surface set.

My first implementation was in C++ and entirely on the CPU which took about 20 seconds to run on a mesh with ~10,000 triangles and a 503 voxel volume.  In the version I’m presenting here I moved to C#, when I did that time went up to about 60 seconds.  So I ended up porting a similar version of the CPU implementation to the GPU using OpenCL (Cloo), on the same data it ran in about 6 seconds on my Nvidia 540M, with no attempt to optimize.

One unfortunate limitation of Schwarz’s solid voxelization algorithm it that it requires watertight meshes.  The reason for this is you’re shooting a ray down a column of voxels until you intersect with a triangle.  You’re then xor’ing the bit for each voxel signaling that this column of voxel’s is inside or outside.  Voxels that are inside a mesh will be Xor’ed an odd number of times, where as outside voxels will be xored an even number of times.  So if there is a hole in the mesh, you’d leave a incomplete trail of xor’s in that column, leaving every voxel from the last triangle to the bounding box marked as ‘inside’.

Two papers I’ve run across that might contain solutions to this problem are An Automatic Hole-Filling Algorithm for Polygon Meshes and Complete Polygonal Scene Voxelization.

2. Find The Highest Density Voxel

In this step you’ll find the voxel that is furthest away from any external area, and excluding any voxel that has already been enclosed by a box in step 3.  Because the number of empty voxels likely far exceeds the number of voxels touching an empty voxel, you’ll probably want to test against that list instead of determining the distance from the closest empty voxel.

For my project this was implemented on the CPU, but this is probably something you could do faster on the GPU if this ever became too slow for your needs.

3. Box Expansion

Once you’ve found the densest voxel you’re going to create a 13 voxel sized box at that location.  You’ll then proceed to iteratively expand each side of the box in voxel space until you can’t expand any side of the box without entering an empty voxel or another box that has already been placed.

As you verify each expansion of the box you’ll mark the enclosed voxels in such a way so that the next time you choose the densest voxel you can exclude any already enclosed in a box.

Currently the expansion order is uniform, however, I suspect a better approach would be some small amount of prediction allowing me to grow one side more than another to maximize the potential volume of each box. 

The best implementation of this AABB expansion methodology would be to use an optimization solver, but that could potentially take quite awhile to run.

I’m still looking for alternatives to the AABB box expansion method of generating the simplified geometry. The axis aligned boxes aren’t the best for models at non-right angles.  Perhaps a better approach could be divined with OBBs but that’s just conjecture.

I briefly considered the Iso-Surface method Xi Wang mentioned in his Automated Level of Detail Generation for HALO: REACH talk at GDC 2011 but that generates a lot of triangles and a volume larger than the voxel volume you start with. So that just gets us right back to the problem we started with.

4. Repeat 2-3

I ended up having two different stopping conditions.  If an absolute percentage of the remaining volume is met I stop adding new boxes.  Alternatively if the last box created consumed too small a percentage of the total volume that also stops the box expansion process.

Some other things I didn’t implement but that could be tried are, setting a maximum number of boxes, or a box too small (in voxel space, instead of percentage) as a cutoff point.

5. Filter Boxes

This portion of the technique I haven’t tried but makes a lot of sense depending on your stopping condition.  If several small boxes are generated before one of the cutoff conditions is met during step 4, you’ll probably want to ignore them before moving to step 6 to reduce your occluder triangle count.

6. Merge Boxes With Constructive Solid Geometry

Drawing individual boxes even as a single draw call would cause lots of overdraw.  Instead we should take our collection of boxes and combine them into a single mesh before we finish.  To do this we’re going to use Constructive Solid Geometry (CSG).

Soon after I realized I was going to need CSG (or something akin to it) to solve this problem I was informed of a new book, Game Development Tools.  In that book there is an implementation for Real-Time Constructive Solid Geometry written by Sander van Rossen and Matthew Baranowski.  The implementation is pretty slick and I was able to get it up and running pretty quickly.

The Results: Time-Lapse

The box expansion runs in a fraction of a second, but I slowed it down and broke it up over several frames so that you could see how the occlusion shape evolves.

YouTube Preview Image YouTube Preview Image

The Results: Different Models

To get an idea of the results on different models I’ve provided some screenshots.  The settings I used for these was to cutoff after 90% of the volume had been consumed by boxes.

occluder_results_1 occluder_results_3
occluder_results_2 occluder_results_4

Notes

In situations where the technique doesn’t work very well allow an artist to specify a custom mesh.  In some cases an option to use the same mesh for both the visual and the occluder would probably be a good idea (like for planes).

To reduce draw calls you will likely want to generate the occluders during export time.  Then during the cook stage in your level editor, merge some number of the occluders together to reduce draw calls.

Download

works_on_my_machine
Voxelization Occlusion Generator.zip

License: MIT

Thanks

Thanks to Michael Noland and Shaun Kime for letting me bounce ideas off them.  Also thanks to Stephen Hill for telling me about Rossen / Baranowski’s Constructive Solid Geometry implementation and for giving me feedback on this post.

Hubert’s Safari Adventure: Development Diary

1/28/2011 6:00 PM

We just finished hearing the keynote given by Keita Takahashi.  Just like his games…it was different.  Seems like a guy that would be interesting to hang out with.  We’re now forming our groups.  The theme this year is "Extinction".  Awesome, finally something simple and concrete.

1_29_2011_-_6_30___1

1/28/2011 7:00 PM

Groups have formed, I joined the group making a global control game.  Where you adjust the temperature, cloud cover…etc to control evolution and attempt to prevent extinction on the planet.

1_29_2011_-_7_45___1

1/28/2011 9:00 PM

We’re back from dinner.  Mmm Mellow Mushroom.  My cold is getting worse, I will probably leave early.  We’re batting ideas around, very difficult to make this game concept fun.  Lots of variables.  I fear this game is becoming Sim Earth, but like a version built in 48 hours and even more pointless.

1_29_2011_-_9_00___1

1/28/2011 10:00 PM

Still going over the game idea, Mike is checking in our initial solution to work with.  The game idea is feeling less fun by the minute.

1/28/2011 10:30 PM

I’m heading home.  I tell everyone to find the nugget of fun or abandon the idea.  I’ll login from home and work on some GUI stuff, this game feels very GUI heavy for all the knobs and sliders you can play with to control things.

1/28/2011 11:30 PM

I fall asleep on the couch.  Thanks NyQuil.

1/29/2011 12:03 AM

I have received an email from Mike:

We are making a totally different game.

Nonsensical dodo slayer

You fire anvils, fireballs, and piranhas at a giant flock of dodos, etc…

We’ve actually come up with a solid plan, tho it doesn’t sound like it.

1/29/2011 9:00 AM

I’m awake.

1/29/2011 10:00 AM

Alright ready to go, need to go by the store and get some DayQuil and various other supplies to keep me awake and coding.

1/29/2011 11:00 AM

I’ve arrived to the Jam Site, need to get setup and understand the plan for the new game idea.

1/29/2011 11:01 AM

Ok, the idea is to make a nonsensical dodo slayer.  Appears the email was quite accurate.

1/29/2011 12:45 AM

There is a title screen and some random dodo things that move around.

1_29_2011_-_12_45___1 1_29_2011_-_12_45___2

1/29/2011 2:30 PM

We’re finally off and going, tummies full of food.  The art is looking pretty awesome.  Like a cross between Elmo and a dodo.

1/29/2011 3:15 PM

I’m working on the firing system.  Woo!  Simple target aiming system for now.  Will revise for maximum fun as we go.

1/29/2011 3:56 PM

I’m firing attractors into the level.

1_29_2011_-_3_56___1

1/29/2011 4:16 PM

I love DayQuil.  I’m losing my voice.  Lame.

1/29/2011 4:37 PM

We’re getting the first drops of actual art into the game.  Those poor dodos have no idea what’s about to happen to them.

1_29_2011_-_4_38___1

1/29/2011 5:04 PM

I’m working on the animation system, going to make the animation playback scale so that when the dodos get scared their animation rate doubles or triples.  Should provide a lot of humor.  The buy screen is in, so that people can purchase items to be used.  The background appears to have odd gamma rendering artifacts.

1_29_2011_-_4_51___1

1/29/2011 6:18 PM

Spirits are high, the comedic humor of the art is good.  We’re working on making the poor dodos explode.  Anvils and ice-cream make an appearance, but don’t do anything yet.  We found out the DCC tool the artist was using to render the background was encoding source gamma information into the image, but XNA doesn’t respect that information.  Gamma fixed.

1_29_2011_-_6_20___1

1/29/2011 6:34 PM

Playing with XACT 3.  This tool needs some usability love…

1/29/2011 6:49 PM

The end is nigh.  Abandon all hope all dodos that enter here.

1_29_2011_-_7_08___1

1/29/2011 7:39 PM

I’ve got the sounds in for the splat, and the and the birds, the sounds truly bring the visceral dodo destruction to life.  The volume of the flock actually varies over time based on the number of the dodos left.  We need epic music now.

1/29/2011 7:40 PM

I love DayQuil.  My voice is almost completely gone though.

1/29/2011 7:45 PM

Chris has the blood spray working, it looks awesome.  Things are coming together.

1/29/2011 7:56 PM

Looks like we have 2 levels, with a 3rd one on the way.  I’ve suggested Antarctica with the aura borealis…that seems to have caught on.  Should be interesting.  Getting Hungry.

1/29/2011 8:21 PM

Stopped to have a brainstorming session to get people to determine the priority of items left, created a list of things to do.  We’ve still got a fair amount of work to do.  But the game should be very comical and pretty.

1/29/2011 9:12 PM

Alex has added a simple HUD.  I’m getting Hungrier.  Voting on food locations is not working.

1_29_2011_-_9_10___1

1/29/2011 11:23 PM

Cold is fighting back.  Going home soon.

1/29/2011 11:50 PM

Still here but in a daze from the cold.

1_29_2011_-_11_40___1

1/30/2011 12:22 AM

I’ve added the level transition logic.  Going home.

1/30/2011 3:00 AM

Sleep.

1/30/2011 8:00 AM

Awake. 

1/30/2011 9:30 AM

I’m back at the jam site.  I appear to be the first one here and awake.  Someone is sleeping in the room.  Will go find somewhere else to work until they wakeup.

1_30_2011_-_9_40_am___1

1/30/2011 10:30 AM

I’ve decided to change the HUD.  Changing the button layout to be spatially map-able to the Xbox 360 controller.  Fixing some sound issues.

1_30_2011_-_10_30_am___1

1/30/2011 11:20 AM

Level transitions are working-ish.  Making the HUD text outlined so that it’s easier to read.  BURN DODO BURN!  Mike has integrated the burning animation into the mix.

1_30_2011_-_11_20_am___1

1/30/2011 11:40 AM

Final targeting cursor is in.  The artists are working on some sweet store / score and credits screens.  We’re also getting some art of the dodo for the title screen.  The consensus is a dodo with an “The end is nigh” sign.

1/30/2011 12:00 PM

Looks like we’re working through lunch.

1/30/2011 1:00 PM

Chris added some alpha blended boxes behind the text to get them to stand out from the background in the store.  I fixed some bugs with the animation system that was causing flipbook wrapping when the animation playback was scaled.

1_30_2011_-_2_00_pm___1

1/30/2011 2:00 PM

The finishing touches are going into the game now.  Making sure everything resets properly after each new game.

1/30/2011 2:30 PM

Adding the music into the game.  Removing the background dodo sounds, just keeping the hurt dodo sounds.

1/30/2011 3:00 PM

Game Over.  Game looks pretty good and it’s fun.  Everyone did a wonderful job.

1_30_2011_-_3_00_pm___1

Hubert’s Safari Adventure

The Global Game Jam 2011 has ended.  I present to you the labors of me and my team.  The theme this year was “Extinction”, which I’m happy to say I loved.  I was very happy that the group organizing the global game jam finally figured out they need to focus on something simple and concrete for the theme.

Description

A game for one player using an Xbox controller or keyboard and mouse, wherein you exterminate dodos for a tyrannosaur named Hubert.

- Hubert runs a park with the allegedly extinct dodo.
- You have gotten a pass to go hunting on his lands.
- Kill as many dodos as you can in the time limit.
- Use ice cream to attract the dodos, and then crush them!
- Drive them before you! Hear the lamentations of the hens!
- Bonus time and money is awarded for high-efficiency extinction.
- The game ends when time expires.

Team

  • Alexander C. Park
  • Autumn Ford
  • Chris VanderKnyff
  • Harrison Moore
  • Michael Kelley
  • Michael Noland
  • Nick Darnell

Video

YouTube Preview Image

Download

HubertsSafariAdventure_v1.zip

Requirements