A 3D software rasterizer built from scratch in Java. This project implements the core concepts of computer graphics, including 3D transformations, perspective projection, depth buffering, backface culling, and lighting - all without using any external graphics libraries.
- Custom 3D Pipeline: Complete graphics pipeline implemented from scratch
- OBJ Model Loading: Parse and render standard .obj 3D model files with texture coordinate support
- Real-time Rendering: Smooth 60 FPS rendering with interactive camera controls
- Depth Buffer (Z-Buffer): Proper occlusion implement (model visibility)
- Rendering Modes:
- Wireframe mode for visualization and debugging
- Rasterized mode with lighting and shading
- Texture Mode for realistic textures
- Interactive Camera:
- WASD keyboard controls for camera movement
- Mouse drag (right) for model rotation
- Mouse drag (left) for camera rotation
- Mouse wheel for zoom
- Lighting System: Directional lighting with diffuse shading and ambient light
- Backface Culling: Automatic removal of back-facing triangles for performance
- Perspective Projection: Proper 3D to 2D transformation with field of view
- Clone the repository:
git clone https://github.com/jahaanb7/Software-Rasterizer.git
cd Software-Rasterizer- Compile the Java files:
mkdir bin
javac -d bin src/main/engine//*.java
cp -r resources bin//- Run the application:
java -cp bin src.main.engine.rasterizerSoftware-Rasterizer/
├── src/main/engine/
│ ├── rasterizer.java
│ ├── LineDrawer.java
│ ├── DepthBuffer.java
│ ├── Matrix.java
│ ├── Vector3D.java
│ ├── Vector4D.java
│ ├── Triangle.java
│ ├── Mesh.java
│ ├── OBJLoader.java
│ └── MyMeshes.java
├── resources/
│ ├── monkey.obj
│ ├── sphere.obj
│ ├── rabbit.obj
│ ├── MaxPlanck.o
│ └── homer.obj
└── README.md
�── README.md
The engine implements a complete 3D graphics pipeline:
- Model Loading: Parse OBJ files to load models from vertices and faces
- Model Transformation: Apply rotation matrices for model rotation
- World Space: Scale and translate model into world coordinates
- Backface Culling: Calculate surface normals using cross product and removes faces that dont face camera
- Lighting Calculation: Compute lighting using dot product with light direction
- Camera Transform: Translate vertices relative to camera position
- Clipping: Cull triangles outside the view frustum (near/far plane)
- Projection: Transform 3D coordinates to show perspective
- Perspective Divide: Normalize coordinates by dividing by the w' component
- Screen Mapping: Convert normalized device coordinates (NDC) to screen coordinates
- Rasterization: Make and fill triangles (render the model)
- Depth Testing: Z-buffering for solving occulation
FOV-based transformation from 3D camera space to 2D clip space:
[f/aspect 0 0 0 ]
[ 0 f 0 0 ]
[ 0 0 -(f+n)/(f-n) -2fn/(f-n) ]
[ 0 0 -1 0 ]
]
where:
f= far plane distancen= near plane distanceaspect= width/height ratiof= 1/tan(fov/2)
- Export your 3D model as a
.objfile (from modeling software such as Blender, etc.) - Place the
.objfile in theresources/folder - In
rasterizer.java, add to the constructor:
Mesh yourModel = new Mesh();
yourModel.tris.addAll(OBJLoader.loadOBJ(
getClass().getResourceAsStream("/resources/your_model.obj")
));;- Update the render method in
paintComponent():
render(myModel, rotation, buffer, screen);Customize rendering parameters in rasterizer.java:
// Screen resolution
public static final int SCREEN_WIDTH = 800;
public static final int SCREEN_HEIGHT = 800;
// Camera settings
private final int fov = 90; // Field of view (in degrees)
private final double near = 1; // Near clipping plane
private final int far = 550; // Far clipping plane
// Model settings
private double zOffset = 5; // Distance away from camera, will not need in future updates
private double scale = 1.0; // A Scale factor for the model
// Performance
private final int fps = 60; // frames per second, higher means more lagging in this application
private double cam_speed = 0.10; // Camera movement speed