Description
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#.
Features
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; light.Normalize(); //transform the light into tangent space light = TBN * light; light.Normalize(); Vector3 viewDirection = SREngine.SRSystem.Camera.Origin - pos; viewDirection.Normalize(); //transform the view vector into tangent space viewDirection = TBN * viewDirection; viewDirection.Normalize(); //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; normal.Normalize(); //N.L 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()); }