Friday, March 25, 2011

Raptor Racers Week 10

I skipped week 9 by accident, but there has been quite a bit of progress since I last posted. The animation system is mainly done, and looks a lot smoother because I cut out the 'secondary Pose' and interpolating parameter entirely. It was not needed at all, and the animations actually look smoother and work better without it, especially transitions from pose-to-pose.

Now, with lots of help from Brent Cowan (our Graphics TA), I've developed a proper cel shader which looks totally awesome! Cel shading tutorials online (like lighthouse3D for GLSL) also helped, and provided me with information and know-how to understand how a cel shader does what it does.


Above is an image contrasting my shader vs OpenGL default lighting. There are actually 2 separate shaders working to achieve this effect.

 The first shader is a shader that does the outlines. The shader file itself is actually very, very simple. All it's doing is moving a vertex along the normal to 'fatten' the model. I'm telling OpenGL to disable lighting (so that it's one solid colour), and to cull faces that face the camera, as opposed to away from the camera before the shader is actually used. The back-face colour is what makes the colour of the outline, the shader can take that as a parameter (colour) and also line width. That way, we can have different line thicknesses and colours for each object, or even a different state of the same object.

This would be something like a 'selected' effect

The second shader takes care of the lighting, and actually draws another teapot inside the 'fattened' version. Depending on the angle between the normal and the light, the shader just clamps diffuse/specular (etc.) values in a certain range. This can be done for a variety of light types, not just diffuse.

Diffuse + Specular cel shading
Small white highlights for something shiny (like a robot raptor!).

'Glassy' + Diffuse + Specular
 I'm not sure what the glassy effect would be used for, but I modified Brent's code for edgeGlow and fillLight to be cel shaded. It's there if we need it. All of these effects are under the lighting shader. Our game can pass a parameter to the shader and tell it to use/not use different effects (diffuse is required, obviously).

The darker areas look a bit gray due to the ambient value, I'm not sure if either looks better.


Without the ambience, the black outlines blend into the teapot, so we're going to stick with ambience for now.

Saturday, March 12, 2011

Raptor Racers: Week ... 8? I think

Wow, it's been quite a while since I last blogged, I guess my excuse would be midterms and my internet being out for two weeks, but mostly it's just me forgetting. Anyways, let's get down to business.

I remember mentioning a while ago that I wanted to implement a better animation system in our game that can support multiple blend poses (secondary and primary poses), and for the most part, I am done this system now. It works fairly differently than what we had implemented before. What happened earlier is that all the animation system would do when called is set what the next pose would be, and let the drawing function for each raptor determine the actual positions of the vertices & normals that correspond to the model. Each raptor would call this drawing function one at a time, and all of the code used to be in main, and it looked fairly ugly. The new system takes up a bit more memory, but I hope it proves itself to be more useful and flexible down the road. This new system, first of all, cleans up all of the animation code out of main, and in a special function in RaptorClass that gets called by the player and each raptor AI. I have an OCD-like tendency to clean up main as much as possible, and seperate everything into classes. Unfortunately this is a luxury when trying to code something up really fast, and this is the reason why our original animation code was all over the place. RaptorClass also recieved a couple of new member variables. One of which is fairly huge, which is an ObjLoader object. There are several huge arrays for storage of vertex/normal/texture information, and I'm not sure why they are this way. Apparently messing with the max values completely screws up our texturing, and sometimes our normals. I have a suspicion that not all the arrays need to be that huge (10,000+ max size!!!), and that only one array needs to be big enough to store all the information related to faces. I don't know though, I'd have to bring this up at the next group meeting. The other variables are pretty insignificant, and are just integer values.

One new function was written to take care of just the interpolation. The theory is that instead of drawing the object as soon as you interpolate it (our old system), you do all of the blending in one place multiple times to achieve in-betweens of different poses and store that in memory. All you'd have to do in the render function is just to draw the information that is in the variable stored in the RaptorClass (our new system). I'm hoping this will be somewhat more efficient, because the actual math is all being done in one place, and in bulk, separate from the drawing.

A pretty significant downer I did not anticipate though, is that when blending multiple poses together the latest pose often takes precedence. This produces a result that looks almost exactly the same as the previous animation system. Maybe it's just the way I'm blending, because the theory sounds to be correct.

I may tweak the code in the future for the animations to be more dynamic. Right now, I'm going to try to focus more on shaders, getting a proper HUD to work, our very simple 'level creator' or maybe trying to fix textures (using PNG's instead of BMP's due to size issues).