Screen Space Shading

One new technique in size coding is screen space shading. The idea is to avoid lots of shader code or even host code and produce shading code purely in screen space in the fragment shader.

For example, suppose we wish to do phong shading. Normally we would need to do the following:

1. Submit vertex normals
2. Write a vertex shader to output normals at vertices and the eye position
3. Write a fragment shader to normalize these
4. Calculate lighting

Instead though, steps 1,2 and 3 can be avoided and the normal recovered just from the pixels in the screen. GLSL offers a couple of functions dFdx and dFdy. These tend to work on cards supporting PS3.0 and later. In essence they give us the rate of change of a value across pixels. So recovering a normal in screen space can be written in GLSL as:

vec3 n=normalize(vec3(dFdx(gl_FragCoord.z),dFdy(gl_FragCoord.z),1));

If you are familiar with height maps and deriving normals, thats exactly this equation. There are issues with borders of objects which can result in a black border round the object, but this can also be exploited as a special effect.

Another effect that can be done in screen space is Ambient Occlusion. Iq of rgba has published a few articles on this and the technique seems to have been first used by Crytek. Essentially, in the fragment shader, a number of points are generated around the surface normal in world space. These are samples for the AO. These are then projected into screen space again and their depths tested against the pixels they project to. If the point is further away in z, that sample is occluded. The results are summed as you might expect.

Here is an image from Kindernoiser by iq of rgba using this technique. It is amazing just how well it works! Its fast, dynamic and less code than traditional AO techniques.

There are drawbacks of screen space shading. For example, take a sphere subdivided into a number of flat polygons. With standard normal interpolation the sphere will look smooth as the normal is interpolated across the pixels as if the surface is curved. In screen space, we have only local information so the flat surfaces still look flat. Nontheless advantages in size can be worth it.

Slight update:
Here are some more images of screen space (or image space) illumination. Quite extraordinary. I must get an image space renderer written.



  1. Anonymous15/10/07

    cool article, thx


  2. Thanks for that phr. I'll try to extend the idea and present some real code in the future.

  3. Anonymous16/10/07

    it is really amazing that a 4k intro can use the same technology as a top-level game (Crysis)