
My first commercial release! All the hard work and late nights paid off!
Kung Fu Panda 2 The Video Game
Ru8n – iPhone Game
Introducing Ru8n in the iTunes app store.

You help a happy-go-lucky square dude escape death by turning his world (the iPhone) left, right, up and down all while he continually skips to his right.

I made the game with my dad
. It uses our engine built off of c++, objective c, OpenGLES, XML and OpenAL.
There are 30+ levels each involving different timing puzzles. Take your time progressing levels or go for a highscore by collecting stars along the way as fast as possible. OpenFient’s online gaming community is used to keep track of leaderboards and achievements.
iPhone App
I have been really busy working on my iPhone game.
I am enjoying:
1) iPhone SDK
2) XCode
3) OpenGL ES
We expect a July 2010 release.
… more on that soon …
Engine Update
Here’s an update on the graphics engine I am building for my last class at DigiPen. Model loading, MTR managing, camera controls, texture managing and fragment/vertex/geometry shaders are all handled by yours truly. One focus I had on this particular engine was setting up a fast/user-friendly post processing system. I’v implemented a system of string-recognized render buffers and post processing fragment shaders that can be chained along to stack post-processing effects until you’ve reach your final picture. Instead of drudging through having to bind FBOs, igniting shader programs and sending uniforms etc., this allows the user to simply say… PostProcess( "MyScene", "ToneMapShader", "MyHDRScene" );. Where “MyScene” is the name of the render target you want to be shaded using “ToneMapShader” and then store the output into “MyHDRScene”. All that is required is an offline step where the user verifies all that is needed by the shader.
Also by going through my system, instructions to GPU are saved by only updating the graphics pipeline when necessary. I can keep track of the current GPU state and thus save time such that if someone wanted to use the same texture sampler on TEXTURE2′s unit there’s no need to re-bind the texture thus saving communication time on the slow bus between CPU and GPU. This can save loads of time and any good graphics engineer needs to be weary of GPU state changes; especially changing shader programs which my system also handles.
This demonstration is ready to run on an Nvidia 6600GT.
Extra Features in Demo:
Beside self-shadowing parallax, I was able to get global shadow maps to work with the parallax occlusion. Because parallax mapping actually takes place on flat geometry, depth comparisons with the light buffer will conclude that something parallaxed is in shadow when it really isn’t; this causes “floating” shadows where no matter how steep the parallax-occlusion becomes, the shadow test still determines shade with the flat piece of geometry. I modified the G-Buffer such that when an object is using parallax-mapping, I alter it’s world-space position in the G-Buffer. This is easy to do via shaders by simply moving the world-space position along the object’s normal*parallax_value.
Deferred Lighting
Steep Parallax Mapping with Soft Shadows
Variance Shadow Maps
Screen Space Motion Blur
hacked slerp
I don’t want to turn this to a blog about quaternions, but if you are familiar with animation you’ve probably had your fair share of quaternions. Spherical linear interpolation AKA slerp is then used to interpolate between two orientations ( quaternions ). Your generic slerp function would look something like this…
Quaternion Slerp( const Quaternion& lhs, const Quaternion& rhs, float t )
{
float cosAlpha = lhs.Dot( rhs );
Quaternion r = rhs;
if( cosAlpha < 0.0f )
{ // if cos(alpha) is positive, then the path from q1 to q2 is shorter.
r = -1.0f*r;
}
cosAlpha = lhs.Dot( r );
float alpha = acos( cosAlpha );
if( fabs( alpha ) < epsilon )
{ //< these quaternions are too close to slerp between.
return lhs;
}
float a = sin( ( 1.0f - t ) * alpha ) / sin( alpha );
float b = sin( t*alpha ) / sin( alpha );
Quaternion q = a*lhs + b*r;
q.Normalize(); //< we want a unit quaternion
return q;
}
Lots of slow trig functions for hundreds of slerps can really bog you down.
Well, this article by Jonathan Blow has a nice hack that approximates slerp. It uses generic lerp between two quaternions and then normalizes the quaternion to project it back onto the unit sphere.
Our new code looks something like…
Quaternion Slerp( const Quaternion& lhs, const Quaternion& rhs, float t )
{
Quaternion hackQuat;
hackQuat.x = lhs.x + t*(rhs.x – lhs.x);
hackQuat.y = lhs.y + t*(rhs.y – lhs.y);
hackQuat.z = lhs.z + t*(rhs.z – lhs.z);
hackQuat.w = lhs.w + t*(rhs.w – lhs.w);
hackQuat.Normalize();
return hackQuat;
}
Unfortunately, where slerp moves through at constant speed, linear interpolation moves quickly at the endpoints and slowly in the middle; worst case being where the original angle b/t quaternions is 90degrees. They fix this by "splining" t to compensate for the speed issues.
I decided to put both methods to the test in my homemade animation loader/updater/viewer! Each bone only has a maximum of 16 keyframes creating pretty decent angles between orientations. Can you tell which is which?!
Of course, a better method would be to just implement incremental slerp which is both computationally fast and takes care of any speed issues.
Soft Particles
Particles are used everywhere in games for transparent objects like smoke, fog, dust etc; they can potentially add a lot of extra detail and polish. If you’ve ever added particles to your game you’d notice that one major problem is that they produce ugly artifacts and unnaturally sharp edges where they intersect the rest of the scene ( see below ).

Implementing soft particles is a way to alleviate the harsh collision that occurs between particle sprites and existing geometry. If you are doing deferred rendering you probably already have some way of retrieving your scene’s depth buffer. While rendering the particles into your scene, alpha blend out fragments who’s depth is close the the existing scene’s depth. You can make a simple fade out function such as:
D = clamp( ( Zscene – Zparticle ) * scale, 0.0, 1.0 ).
Nvidia’s article on soft particles, however, recommends using a piecewise function or a smoother function to create a nicer fadeout. Here is my soft particle using a smoothing curve.

Too Much is Never Good
Funny things can happen if one shader calculation goes wrong. I was making a screen space motion blur post-proc effect in glsl. I sent the current world-to-view matrix and the previous world-to-view matrix to the PS to find out the pixels previous and current screen-space position from that and blur along the resultant vector. if you happen to accidentally scale that vector, fun ensues!
Maybe I’ll use this accident for a dizzy/drugged effect in my next game.
These titles are getting rather long, but this is just an update to my previous post for a project in my CS562 class. SSAO works on the parallax mapping for free which is pretty nice.
Just an update on a school/personal project. The scene is rendered using deferred lighting, screen space ambient occlusion and variance shadow mapping. There are 300 local lights and 1 global light contributing to all the colors; I just randomly pick the local lights’ position and size to get some interesting looks. Next I want to add some textures and implement ATI’s Tatarchuk “Dynamic Parallax Occlusion Mapping with Approximate Soft Shadows” for the floor and such =P.
Deferred shading is a shading algorithm where information is stored to several intermediate buffers instead of straight to the color buffer. Many times, in forward rendering, lighting calculations will be spent on fragments that end up being overwritten by occluding objects in the scene. The idea behind deferred shading is that we hold off on lighting calculations until needed.
1) Render all the geometry of your scene to a G-Buffer. The G-Buffer will hold fragment normals, positions and any other information you’d need to have later on for your lighting calculation. Usually the following step-up will get you far enough along to see some results…
Render Target1: gl_FragData[0] = 3DPosition.x, 3DPosition.y, 3DPosition.z, Free
Render Target2: gl_FragData[1] = Diffuse.r, Diffuse.g, Diffuse.b, Specular
Render Target3: gl_FragData[2] = Normal.x, Normal.y, Normal.z, Free
However, you’ll want to optimize this setup based on your hardware caps.
Tip: Storing only Normal.x and Normal.y you can re-derive Normal.z later knowing that it has unit length.
Tip: You derive Position.xyz for each pixel by using 2D screen coordinates and a reconstructed linear depth.
2) Now that you have the G-Buffer you can run your global lighting shader by passing in the G-Buffer and exciting each pixel on the screen with a full-screen quad. The global lighting shader will use the information from the g-buffer to light everything on screen.
3) Local lighting works the same way. “Excite” only the pixels you want to light by rending small spheres or cones or whatever. This will, in-turn, ignite the fragment shader to work on only parts of the scene that are effected by each local light.
4) Sky’s the limit… do what ever post-processing effect you want. Just know that the idea here is run calculation on as few pixels as possible. If you have 100 HUGE local lights that fill the entire screen 100xtimes over, you’re missing the point.
There are many optimizations to be have, I’ll touch on these later.
PS: I created the cloth using springs and Verlet integration.
Hierarchical Occlusion Maps
1) A pre-process step concludes which objects will make good occluders;
2) after which these “big guys’” AABB is rendered to the scene each frame in low resolution.
3) Using depth and stencil information we can then figure out which objects are occluded from the occluders using simple AABB calculations.
This technique works great to cull out complex objects in scenes where one object can play a significant roll in occluding others ( ie., forest canopy ).




