A real-time 3D software renderer built from scratch in C# using Windows Forms. This project implements a complete rendering pipeline without relying on GPU acceleration or graphics APIs like OpenGL/DirectX.
Rendering.mp4
- Fast Bitmap Access: Optimized pixel operations using unsafe code and direct memory access
- OBJ Model Loading: Parse and render Wavefront OBJ files with vertices, texture coordinates, and normals
- View Frustum Clipping: Polygon clipping against all six planes of the view frustum
- Scanline Rasterization: Triangle-based rendering using the scanline algorithm
- Texture Mapping: Perspective-correct texture mapping with proper UV coordinate interpolation
- Z-Buffer: Depth testing for correct occlusion handling
- Back-Face Culling: Skip rendering of triangles facing away from the camera
- Lighting: Diffuse and ambient lighting model with configurable coefficients
SoftwareRendering/
├── Form1.cs # Main application window and render loop
├── Scan Line Rasterizer/
│ ├── ScanLineRasterizer.cs # Core triangle rasterization and mesh rendering
│ ├── Vertex.cs # Vertex data (position, UV, normal) with transformations
│ ├── Edge.cs # Edge interpolation for scanline traversal
│ └── Gradient.cs # Gradient calculations for attribute interpolation
├── Meshes/
│ ├── Model.cs # OBJ file parser
│ └── Mesh.cs # Mesh wrapper combining vertices and faces
├── Transform/
│ └── Transform.cs # Matrix transformations and perspective divide
├── SharedData/
│ ├── FastBitmap.cs # High-performance bitmap pixel access
│ ├── SharedConstants.cs # Display and lighting configuration
│ └── SharedMethods.cs # Utility functions
├── 3DStarfield/
│ └── 3DStarfield.cs # Bonus 3D starfield effect
└── Resources/
├── *.obj # 3D models (monkey, icosphere)
└── *.jpg # Texture files
- Model Loading: OBJ files are parsed to extract vertices, texture coordinates, normals, and face indices
- Transformation: Vertices are transformed using model-view matrices (scale, rotation)
- Clipping: Triangles outside the view frustum are clipped using the Sutherland-Hodgman algorithm
- Screen Space Conversion: Vertices undergo perspective divide and screen space transformation
- Rasterization: Triangles are filled using the scanline algorithm with attribute interpolation
- Shading: Per-pixel lighting is calculated using vertex normals and a directional light source
- Texturing: Texture colors are sampled with perspective-correct UV coordinates
- Depth Testing: Z-buffer ensures correct visibility ordering
- Scanline Rasterization: Triangles are sorted by Y-coordinate and filled line by line, interpolating attributes along edges
- Perspective-Correct Interpolation: UV coordinates and depth values are divided by W before interpolation, then multiplied back
- View Frustum Clipping: Polygons are clipped against each axis using the
wcomponent as the boundary
- .NET 8.0 SDK
- Windows (Windows Forms dependency)
cd SoftwareRendering
dotnet build
dotnet runOr open SoftwareRendering.sln in Visual Studio / JetBrains Rider and run the project.
Edit SharedData/SharedConstants.cs to modify:
// Display settings
public const int PictureSizeX = 720; // Window width
public const int PictureSizeY = 720; // Window height
// Lighting settings
public static readonly Vector4 LightDirection = Vector4.Normalize(new Vector4(2, 2, -1, 0));
public const float DiffuseCoefficient = 0.9f;
public const float AmbientCoefficient = 0.1f;smoothMonkey2.obj- High-poly Suzanne (Blender monkey) with smooth normalssmoothMonkey0.obj- Low-poly Suzanne with smooth normalsmonkey0.obj/monkey2.obj- Flat-shaded variantsicosphere.obj- Subdivided icosphere
bricks.jpg,bricks2.jpg- Brick textures for testing
FastBitmapclass uses unsafe code withLockBitsfor direct pixel access, significantly faster thanBitmap.SetPixel- Z-buffer is stored as a flat float array for cache-friendly access
- The renderer runs on the CPU; performance depends on screen resolution and model complexity
This project is for educational purposes, demonstrating fundamental 3D graphics concepts without hardware acceleration.