DorkbotPDX Exquisite Corpse


I contributed to this project. I can’t reveal details until we reveal the whole project!

(PS: We did complete this project)

The Missing Link

I created the initial firmware for the Missing Link. It’s an OSC receiver that outputs MIDI. The purpose is to hook up OSC clients such as TouchOSC or Control to older synths. The source is available here.

Read below for my post mortem notes.

This was my first “large” microcontroller project. It consisted of the following pieces:

Software wise we used the following:

By far, the hardest pieces to get working was communication channels. First, getting I2C working between the PIC and the AVR we used was hard to get reliable. It was hard to even get working initially! I learned the hard way that people interpret I2C address differently. It’s best to spam them all.

Secondly, getting the USB midi code working well was a challenge as well. But it was fun to dive in and learn about USB.

Overall, I learned quite a bit from this project. If I were to do it again, I’d probably not use the Arduino prototype code we started with and go with straight C. The current codebase is a combination of different approaches. But as with a lot of projects, we were working under time constraints.

Processing Class


More pictures

I gave a class on using Processing to create simple graphics. Also quickly “covered” using the OpenCV addon to detect faces. Notes, slides, etc are available here.

It was the first time I’ve taught a class in quite a while. I got a fairly positive response (from my friends, so they have to be nice to me!). I think I did a good job setting up mini-goals that took 20-30 minutes to accomplish. The idea was to give everyone little victories quickly so they’d be motivated to stick around and conquer more.

Morse Code Lights

One of my first electronics projects: Morse code xmas lights. Also here.

Bits and pieces

I actually haven’t done too much rendering work in the last six to eight months.  I’ve been doing a lot of game prototyping.  Two prototypes have been put to the side for now and I’m working on a third with a couple of folks.  I’m just going to dump out some random snippets I’ve learned through that process.

I finally broke a million in Robotron!

Robotron High Score:  1123515

Torque 3D Lighting System Video

Just a quick link post today.  Here’s a video of the lighting system I’ve worked on with Pat Wilson and Tom Spilman. I’m mostly responsible for the dark pixels in the video. ;)

Also, I got a new personal best score at Robotron today: 624k.  I’m slowly inching up to a million.

Probabalistic Shadow Map Technique Comparisions

This is a quick slideshow of screenshots and notes about various shadow map techniques.  I hope to continue adding to this in the future. The notes are pretty terse and probably not useful unless you read the source papers. ;)

Math Debugging

I’ve gotten a late start on this rendering thing.  One of the pieces I’ve been struggling with is math.  I’ve improved quite a bit over the past year and I’m actively educating myself to catch up.  Recently, a friend of mine asked me for some help with a matrix problem.  Here’s what I told him to help him debug (I wish I could go back in time and tell myself this!):

These are just general divide and conquer debugging tips applied to math.  But for a person new to large amounts of math in programming, it can be non-obvious to think about applying those debugging techniques to math problems.  Does anyone out there have their own favorite math debugging tips?

Quick PIX trick

Let’s say you’ve got a render state problem.  If object A is on the screen at the same time object B is on the screen, object A gets screwed up.  Here’s a quick way of using PIX to track it down:

  1. Take a snapshot of the frame that works and a snapshot of the frame that fails.
  2. In PIX, find the draw call that draws object A in the frame that works
  3. Go to the device state tab
  4. Copy and paste each page of state into a text file
  5. Repeat for the frame that fails, save this to a separate text file.
  6. Diff the text files with your favorite diff tool!

This is much easier than trying to diff the states manually within PIX itself.  PIX should have a draw call diff as part of its standard functionalty!

Why are these new shadow map techniques filterable!?

I’ve only been doing graphics stuff seriously for about a year.  One of the first things I tackled was shadow mapping.  I got a simple shadow map implementation going and then implemented Variance Shadow Maps.  It’s based on statistics and the big deal is that you can filter your shadow map and get filtered shadows as a result.  At the time, I didn’t understand why that was true. I had assumed it was a special property of the Chebychev Inequality.  I just implemented it and went on.  Yesterday, I quickly tested Exponential Shadow Maps.  While looking at it, it finally struck me why it was filterable:

These new shadow map techniques are smooth functions based on the occluder and receiver distances to the light!

Above is my Microsoft Paint created graphs (grabbed this style of graphing from Pat Wilson heh). On the left is ESM, you can see that it smoothly drops from 1 (fully lit) to 0 (fully shadowed). So if you massage your shadowmap and you get values on the x-axis (which is occluder - receiver), you’ll see that there will be a border of grey values (basically from -5 to 0 in the graph above, btw this is not what e^(c*o-r) actually looks like, heh). On the right, standard shadow mapping is just a step function. If you move this a little bit below zero, you’re immediately shadowed completely.

This is a also a reason why you don’t need to worry about shadow map bias as much with these new techniques. Because the shadow function isn’t all or nothing, if occluder - receiver is -.9999, you’re going to look basically lit. But in standard shadow mapping, -.9999 is fully shadowed, and you’ll get shadow acne.

So you could draw any random function as a 1d texture and use that for shadow mapping!  These other techniques are just ways of creating that function in a way that is fast and makes sense visually.

The silly thing is that I knew why standard shadow maps were not filterable from the get-go, I just didn’t “invert” my thinking to figure out why these new methods were filterable.