10/07/2011

Special effects!

Have you ever wondered why next-gen games are so much more appealing than the old ones on consoles like N64 or PS1?  You may answer: That's because they run on more powerful machines.
And that's true, but that's not what makes the difference.

If you take an N64 game and port it as-it-is on the more capable Wii, it won't look any better than it did
on the old console. (That's why virtual console games have basically the same graphics of the original games).

To make a N64 game look like a Wii game would require a lot of work of replacing old textures with more detailed ones (at better resolutions which new consoles are capable of), and making more high-poly models. But what really makes the difference are shaders.

What is a shader anyway? Newer consoles have something called programmable video cards, which means programmers can directly tell the video card how they should render models, which wasn't possible on older machines. The standard behaviour would be to leave the vertex positions as they are, and render textures in a standard way. With shaders programmers can change this behaviour, for example by animating the position of models vertexes or blending the texture with an arbitrary color. More advanced uses are projections to create water effects, blur, bloom, fur and much more!

Here's some actual examples from some of my favourite video games:

In "Conker's Bad Fur Day" for N64,
Conker's fur is just a flat texture.

In its remake for XBox shaders are used
to achieve real fur effect.











In "Paper Mario 64" you can see the quality of
textures allowed by N64.
In its sequel for Game Cube, the machine
allowed better resolutions and
more characters on screen.













Back to Bombs & Penguins, one shader effect I'm currently using is rim lighting. If you have ever played Mario Galaxy, it's the effect it heavily uses to reproduce a "light on edges" effect. I'm also using a fur effect (but without shaders as I'll explain later) on this ugly bee (probabily the first boss you'll have to fight):

Fur on the right, rim lighting on the left.


Fur is achieved simply with a noise transparent texture duplicated and scaled in different layers. The result is not bad, but it could be better with shaders. However since I'm still a shader-noob and from game view fur is only slightly noticeable, I may leave it this way :)

Istead, I'm using a Cg shader for rim lighting. Reproducing this effect is simpler than you may think:

Here's what the shader does: it calculates a vector wich points from object vertex straight to camera position. Then it does a dot product between the two. If this product is near to 0 it means it is on the last part of the model the camera can see (In the example above Vertex Normal * Vector Camera = almost 0). If the dot product is positive it means the camera can clearly see that part of the model.

The shader outputs the texture color when this dot product is positive, and outputs white when it's near to 0 doing a linear interpolation to smooth out the effect!

So here's how you would do this in Nvidia Cg shader language:

Vertex shader:
 
 //Calculate dot product in [0, 1] range
l_faceQt = pow( 1.0-saturate( dot(vtx_normal, normalize(mspos_cam-vtx_position)) ), 2);

Pixel shader:
//Interpolate between texture color and backlight color
 float4 tex = tex2D(tex_0, l_texcoord0);
 o_color = float4( lerp(tex.rgb, k_envirLightColor.rgb, l_faceQt) , tex.a );




Nessun commento:

Posta un commento