Kyle Hayward's


Software Rasterizer


This project was the result of my Intro to Computer Graphics course at Purdue in the spring of 2007. During the semester individuals all developed their own software rasterizer. Beginning with vector and matrix libraries, continuing with projection, rasterization and lighting techniques. By the end of the semester each student had a working software rasterizer. In addition to the fundamentals required I also implemented PCF shadow filtering, parallax and normal mapping, depth-of-field, distance fog, and point lighting for extra credit. The rasterizer was developed in C#.


  • Gouraud shading

  • Phong shading

  • Blinn and Phong specular reflection

  • Directional and Point lighting

  • Perspective correct texture mapping

  • Normal mapping

  • Parallax mapping

  • Projective texturing

  • Shadow mapping

  • Environment mapping - skybox and reflection

  • Distance fog

  • Depth-of-Field

  • Bilinear Filtering

  • Linear Camera Interpolation

Screen Shots

Source Snippet

/// <summary>
/// Performs a parallax mapped texture look up
/// </summary>
/// <param name="pos">3D position of the pixel</param>
/// <param name="tu">X Texture coordinate</param>
/// <param name="tv">Y Texture coordinate</param>
/// <param name="TBN">Tangent, Bitangent, and normal matrix</param>
/// <param name="u">X Framebuffer coordinate</param>
/// <param name="v">Y Framebuffer coordinate</param>
private void ParallaxMapping(Vector3 pos, float tu, float tv, Matrix TBN, int u, int v)
    float scale = .06f;
    float bias = .02f;

    Vector3 light = mLights[0].Direction;

    //transform the light into tangent space
    light = TBN * light;

    Vector3 viewDirection = SREngine.SRSystem.Camera.Origin - pos;

    //transform the view vector into tangent space
    viewDirection = TBN * viewDirection;

    //get the height from the depth texture
    float heightColor = mHeightMap.BilinearLookUp(tu, tv).X;
    heightColor = heightColor / 255f;

    //travel along the view direction based on the height
    float height = scale * heightColor - bias;
    float newTu = (height * viewDirection.X + tu);
    float newTv = (height * viewDirection.Y + tv);

    //get the normal and tex values at the new texture coordinate
    Vector3 texColor = mTexture.BilinearLookUp(newTu, newTv);
    Vector3 normal = 2.0f * mNormalMap.BilinearLookUp(newTu, newTv) - 1.0f;

    float diffuse = Utils.Saturate(Vector3.Dot(normal, light));

    //finally calculate the color with diffuse lighting and update the framebuffer pixel
    Vector3 color = texColor * ((mLights[0].Diffuse * diffuse) + mLights[0].Ambient);

    mFrameBuffer.SetPixel(u, v, color.ToColorValue());