I’ve switched to using spherical co-ordinates to encode world-space G-buffer normals. This has a lot of advantages to it, especially for 8:8:8:8 G-buffers. You can now store [Theta, Phi, DepthHi, DepthLo] in the 8:8:8:8 target. Bumping the format to 16:16:16:16 not only gives greater precision, but (depending on the depth resolution you need) you can get an extra channel for information storage. (I was thinking baked ambient occlusion blended with screen-space ambient occlusion, done as a pass before lights are accumulated)
There are a few problems with this, though. The first is the atan2 function. On good hardware, this will not be an issue. My GeForce 8800 chews through any shader I throw at it. My Radeon x1300…not so much. Of course it’s easy to make things run fast on good hardware. The challenge is making it run decently on lower end hardware. This is how I am encoding/decoding G-buffer normals:
inline float2 cartesianToSpGPU( in float3 normalizedVec )
{
float atanYX = atan2( normalizedVec.y, normalizedVec.x );
float2 ret = float2( atanYX / PI, normalizedVec.z );
return POS_NEG_ENCODE( ret );
}
inline float3 spGPUToCartesian( in float2 spGPUAngles )
{
float2 expSpGPUAngles = POS_NEG_DECODE( spGPUAngles );
float2 scTheta;
sincos( expSpGPUAngles.x * PI, scTheta.x, scTheta.y );
float2 scPhi = float2( sqrt( 1.0 - expSpGPUAngles.y * expSpGPUAngles.y ), expSpGPUAngles.y );
// Renormalization not needed
return float3( scTheta.y * scPhi.x, scTheta.x * scPhi.x, scPhi.y );
}
Storing normal.z instead of acos( normal.z ) saves a decent chunk of encode/decode.
So I decided to try to use a lookup texture instead of calling atan2 to encode the normals. I made a 256×256 A8 texture and filled it with atan2 values. The texture can be seen, to the right. This is the code for generating the texture:
for( int y = 0; y < cLookupTexSz; y++ )
{
for( int x = 0; x < cLookupTexSz; x++ )
{
F32 xval = ( ( x / F32(cLookupTexSz) ) * 2.0f - 1.0f );
F32 yval = ( ( y / F32(cLookupTexSz) ) * 2.0f - 1.0f );
U8 &outU8 = atan2Mem->bits[y * cLookupTexSz + x];
F32 atanRes = ( atan2( yval, xval ) + M_PI_F ) / M_2PI_F;
U8 u8Res = mFloor( atanRes * 255.0f );
outU8 = u8Res;
}
}
There is a possible discontinuity when V ≈ 0.5 and U <≈ 0.5. So if normal.y ≈ 0.0, and normal.x <≈ 0.0 than you get some artifacts that won’t occur if you actually call atan2. The A8 format isn’t the issue (I don’t think) because even if you use the actual function, you are still encoding the result to an 8-bit value. The resolution of the texture could be an issue, but doubling the resolution did not effect the error rate, in my tests.
I haven’t quite figured out what to do with this yet. A G-buffer shader is going to be heavy on math, light on texture operations (Well this depends on how you are doing deferred shading. See upcoming ShaderX7!) and doing the atan2 as a texture sample can save a lot of instructions and cycles, depending on the hardware.
Here I thought I was special. Turns out people like Greg Ward have been looking at the LUV color format for HDR rendering for some time now. I’ve been perusing a paper from 1998 by Ward describing the LogLUV format. On one hand I’m delighted that someone else came to the same conclusions as I did. On the other hand, I feel dwarfed by the amount of perceptual testing done by Ward etc, and their use of Log L to make the best usage of their range.
I barely know what log(n) really does
I just attempted one of the dumbest optimizations I’ve tried in a while…
The idea was to remove reliance on the back-buffer depth target so that I wouldn’t have to do a StretchRect on MSAA surfaces for a render target. The plan was to render convex shapes to the stencil buffer, using a stencil z-fail op, then draw with the stencil test enabled, and the depth surface unbound so that the render wouldn’t be tied to an MSAA surface.
After implementing the stencil voodoo, and testing it in PIX, I got as far as commenting out the line that would bind the depth surface. It was only at that point I remembered that the surface I was relying upon does not store only depth.
Winner of the 2007 Palme d’Or, this miserable piece of shit managed to capture the hearts of the Cannes Film Circle-Jerk.
This two-hour boondoggle is like listening to The Vagina Monologues, while watching The Bicycle Thief, only that analogy is a gross misrepresentation of both substance and entertainment, neither of which you will find in 4 Months, 3 Weeks and 2 Days.
The dialog was crap. Maybe something was lost in translation, like why I should give a flying fuck about either of these characters. Maybe the point was that weak-willed people who see themselves as helpless victims of their circumstances, and don’t ever think-through their actions are people to make movies about.
According to the Wikipedia page:
After thinking about the story for a month, Mungiu put down the synopsis in 10 minutes then wrote the screenplay in another month. He revised the screenplay numerous times during productions, rewriting and taking out parts that didn’t seem necessary (some changes were also suggested by discussions with Răzvan Rădulescu, who co-wrote Cristi Puiu’s previous two features).
And you know what, it’s pretty fucking clear that nobody spent any considerable amount of time writing this thing. Below is the short, off-the-top-of-my-head list of shit that was important enough to spend a significant amount of time building up, only to completely ignore:
- The dorm, the dorm-mates, the exams everyone was talking about
- The father of the girl getting the abortion coming to visit the day of the abortion
- The flowers, which occupied a good 5 minutes of dialog about how important they were, how many (48, not 49 or 47) and what kind they were
- The hotel they ended up at. The only thing I could figure out was that the Hotels Mr. Bebe suggested didn’t require him to leave his ID at the door.
- Mr. Bebe fucking forgetting his ID card at the door after giving the girls a good 10 minute lecture
- Why it was even important that the girl went to her boyfriends’ mothers’ birthday party
- Why it was important that said mother made said girl marzipan
- Why the mother would even make marzipan for someone of a lower ‘class’, since a good lot of the discussion at the dinner table was the girl getting insulted by the upper-class families.
- Why the same girl was such a psycho-bitch to her boyfriend
- Why, after making such a big deal about the flowers, and how his mom would know that there were 49 instead of 48 etc, the mom, dad, or other families didn’t make mention of said flowers at all
- Why abortion-girl wouldn’t use or answer the phone
- Why it was important to ditch the fetus via 10th-story garbage chute instead of throwing it in a dumpster.
- Why money seemed like such an issue, yet there was no supporting information about how hard it was to get. Exactly the opposite. “Hey, buy 48 flowers for my mom, no problem right?” “Hey talk to all of these black-market guys and buy shit from them.” “Hey, sure, we can get twice the money we have right now in a few days.”
I could actually keep going, but I’m kind of sick of remembering the movie. If you want to see a good movie that is something sort of like this movie, go see Juno. 4 Months, 3 Weeks and 2 Days was not, as Wikipedia says:
indicative of a broader renaissance in Romanian cinema
and really, if it is, please let me know when Romania gets out of their Renaissance, and into…I don’t know at least the later half of their metaphorical 18th century of cinema. I’ve seen better shit come out of angst-riddled, 2nd year film-students who walk around wearing black eyeliner.
Seriously, Romania, go fucking film some plastic bags blowing in the wind, or something.
Hurray! The 360 lives again. Apparently if you curse at it enough, and try the old NES magic of blowing into it, you too can fix red-rings!
- PS2
- GameCube (hey who borrowed that anyway, it’s been like 2 years)
- GBA (old style)
- GBA (new style)
- Xbox 1 with upgraded hard drive and self-sodered dual-BIOS mod chip, used to develop Marble Blast for a while
Oh, and this guy, PS1 dev kit. Still works…

…and during a boss fight, no less.
There was a little SNAFU with the site, apparently, but my host rules, and the problem is no-more. It motivated me to blog more.
Lets get right down to it:
Guitar Hero II Sucks To Play
The game looks great, but it doesn’t play right. I just returned my copy for a refund because the guitar just doesn’t work. The wammy bar is busted, and I can’t activate Star Power by turning the guitar upright with any kind of consistency. Davey got it to work once with no effort, then we tried a bunch to do it again…and it just didn’t work. We tried turning the guitar upside-down and shaking it…no dice. The input feels lagged even if you do the lag calibration. I still am feeling between 10ms-30ms of lag (it’s kind of tough to say for sure, but it’s off). The whole game feels off. This is probably 100% hardware or input code, because otherwise the game looks fantastic. The textures look great at 720p, leaderboards, PDLC songs…I wanted the game to rule, but it doesn’t play right at all. Playing the game is a lot like trying to do a search in Windows XP. You want to just get in there, do your thing, and get your results. You aren’t looking for Spotlight, but grep would be great…instead you are stuck with the fucking dog which doesn’t give you any of the graphical advantages of Spotlight, and none of the functionality of grep. That’s Guitar Hero 2 for the 360, right now. I want to use this and have it be cool, but it’s just painful right now.
In other news, I got mentioned along side Mark Rein in an interesting article. I’ll have to buy him a beer sometime.
If you’re in Eugene, I’ll be playing on May 5th for Prophecy V. I’ll be playing progressive house for my chill-area set, and I may have a main room set. If I play a main floor set, I will probably play progressive trance/psy. I don’t know what name I’ll be playing under; I told my friend to just make something up. Honestly, as long as they think “that guy with the laptop” plays good music, I don’t care what they think my name is. As always, I’ll record the set and put it up for download.
I just wanted to quickly say that I don’t want to give the impression that there is no chance for the Marble Blast Ultra update. I just wanted to provide a realistic view of the current situation. If there was no chance of it happening, than we would have made an official announcement, and if that turns out to be the case, than one will be made.
I have hope for the New Year. Things get mighty-gummed up in the months before the holidays. I also don’t want to create hope where there shouldn’t be, though. No matter what happens, though, Marble Blast will not go away. We started talking about new game modes before we shipped the first one, and this will not be the last Marble Blast. One of the privileges of working at GarageGames is that it is not anyones job to churn out sequels as fast as we can. We get to try new things, new games, new tools, and this helps us from stagnating. We will make a new Marble Blast game in the future, though not the immediate future.
I want to thank the people who have commented and e-mailed in support of Marble Blast Ultra, and I want to make it clear that we hear you, we agree with you, and this surge of energy around Marble Blast may just help to grease some wheels.
I saw the comments and I haven’t looked at the Xbox Live boards in months, but I guess the hiding is over.
Guys it really sucks just as much for us as it does for you, but currently we are unable to come to an agreement with our publisher for the Marble Blast Ultra update. We do not have the power to update the game, and so all I can do is apologize.
This news really should have gone out sooner, I just don’t think anyone wanted to deliver it. I understand the frustration and the let-down, but I do not think, at this point, that there will be a title update to Marble Blast Ultra. I am sorry.
So there have been significant complaints about me not blogging, and not putting up new mixes. I hope to disapoint both groups by posting a short blog entry, and a 1 hour mix
This mix is pretty different from what I usually play at first listen, however since I’ve been able to identify things I like about tracks a bit better, it’s really not that different. It’s melodic, and it has strong bass-lines, it’s just mostly progressive house instead of electro or trance. It’s also one of the best mixes I’ve done, in my opinion, except for a few moments when the DJ had too much beer and forgot which channel had which track on it.
At work I’ve been deep in the guts of the Xbox 360 tech at GarageGames. Almost everything on the 360 side has been re-written and I’ve gained a totally new understanding and appreciation for both the hardware and, especially, the low-level API ‘XG’.
At home, I’m still adjusting to life on the Mac. I find myself using option-tab to scroll-through windows instead of F8 and stuff like that. Ableton 6 runs like a dream on it, and Ableton 6 is a significant upgrade, in my opinion, from 5. I’m glad I bought it, for sure.
Tracklisting:
- Amphibian - Freza Futuristic Mix
- Free Yourself - Original Mix [Loop from: Nino Santiago - Believe - Max Graham’s Sidechain Mix]
- Epidemic - Umut Gokcen Remix
- Susan - Original Mix
- Interadonna - Original Mix
- Instinct - Emersia vs. Storyteller Remix
- Santiago - Hernan Catteno Mix
- Floating Free - Original Mix
I’ve got a ton of stuff to do before I leave tomorrow morning. So that’s all you get.




Recent Comments