Một software rasterizer viết bằng Odin — toàn bộ quá trình vẽ 3D được tự làm bằng code, không dùng GPU, không dùng OpenGL hay DirectX. Mỗi pixel trên màn hình đều đi qua từng bước được viết tay trong code.
Project này được xây dựng để hiểu từ bên trong cách một GPU thực sự hoạt động — bằng cách tự viết lại toàn bộ graphics pipeline ở tầng CPU. Thay vì gọi API đồ họa như OpenGL hay Vulkan như một hộp đen, mọi bước từ transform đỉnh cho đến tô màu pixel đều được implement thủ công và có thể quan sát trực tiếp qua các debug mode.
Tải bản nightly cho Windows ở https://odin-lang.org/docs/nightly/
odin-windows-amd64-nightly+2026-04-02.zip
Giải nén và copy phàn bên trong vào C:\odin với thư mục odin.exe nằm ngay bên trong : "C:\odin\odin.exe"
Sau đó thêm C:\odin vào PATH. Kiểm tra:
odin versionOdin trên Windows cần MSVC linker. Tải Visual Studio Build Tools tại
https://learn.microsoft.com/vi-vn/visualstudio/releases/2022/release-history#release-dates-and-build-numbers
Khi cài, chọn workload: Desktop development with C++
build.batLoad model OBJ tùy chọn:
build.bat model.obj
build.bat model.obj texture.tga- Model / View / Projection matrix — biến đổi đỉnh từ object space → world space → camera space → clip space
- Perspective divide — chia clip coordinates cho w để tạo hiệu ứng phối cảnh xa-gần
- Viewport transform — map NDC
[-1, 1]sang pixel coordinates - Backface culling — loại tam giác quay lưng về phía camera bằng dot product của face normal và view direction
- Edge function (Pineda) — xác định pixel nào nằm trong tam giác bằng cross product 2D
- Barycentric coordinates — nội suy depth, UV, normal, color tại mỗi pixel trong tam giác
- Perspective-correct interpolation — nội suy trong không gian clip (chia cho w) thay vì screen space để tránh distortion
- Z-buffer (depth buffer) — so sánh depth tại mỗi pixel, chỉ vẽ pixel gần camera nhất
- Flat shading — tính lighting một lần cho cả tam giác từ face normal
- Gouraud shading — tính lighting tại từng đỉnh rồi nội suy qua barycentric coords
- Phong diffuse —
intensity = max(0, dot(normal, -light_dir)) - Texture sampling — map UV coordinates sang texel, wrap mode lặp lại
| Khái niệm | Thấy ở đâu trong project |
|---|---|
| Camera intrinsic matrix | Projection matrix (FOV, aspect ratio, near/far) — tương đương ma trận K trong camera calibration |
| Camera extrinsic matrix | View matrix (look-at) — tương đương `[R |
| Coordinate systems | Object space → World space → Camera space → NDC — pipeline chuẩn trong reconstruction |
| Surface normal | Debug mode 3 (Normal map) — encode hướng bề mặt thành màu RGB, nền tảng của NeRF và NeuS |
| Depth map | Debug mode 2 (Z-buffer) — cấu trúc dữ liệu cho stereo matching, SLAM, depth completion |
| UV / texture mapping | Debug mode 4 — hiểu cách project 3D surface xuống 2D, dùng trong photogrammetry |
| Perspective projection | Perspective-correct interpolation (phím P) — lý do tại sao phải chia cho w |
| Homogeneous coordinates | Clip space với w ≠ 1 — nền tảng của projective geometry |
| Khái niệm | Thấy ở đâu trong project |
|---|---|
| Graphics pipeline | Toàn bộ flow: vertex processing → rasterize → fragment → framebuffer |
| Framebuffer & Z-buffer | Hai mảng song song, clear mỗi frame, ghi pixel theo depth test |
| Backface culling | Tắt qua phím B — thấy ngay tại sao GPU loại ~50% tam giác trước khi rasterize |
| Z-fighting | Tắt Z-buffer (phím Z) — hiểu tại sao depth precision quan trọng |
| Mesh structure | Face list với vertex / UV / normal index riêng — cấu trúc OBJ / FBX thực tế |
| Vertex normal averaging | Phím N — tại sao Gouraud shading cần smooth normals ở góc mesh |
| Flat vs Gouraud shading | Phím F1/F2 — tradeoff giữa tốc độ và chất lượng shading |
| Orbit camera | WASD/QE — view matrix rebuild mỗi frame theo eye position |
| Texture coordinates | Interpolate UV per-pixel, sample checkerboard texture |
| Debug visualization | Stats panel, pixel inspector, wireframe overlay, normal arrows — tooling chuẩn của game engine |
src/
├── main.odin — App loop, input, render orchestration
├── pipeline.odin — Vertex transform: model/view/projection
├── rasterizer.odin — Triangle rasterize, z-buffer, shade_pixel
├── framebuffer.odin — Framebuffer, ZBuffer, G-Buffer (PixelInfoBuffer)
├── debug.odin — Stats panel, pixel inspector, overlays
├── mesh.odin — OBJ loader, built-in cube
├── texture.odin — Texture load (TGA), checkerboard, sampler
├── math.odin — Vec2/3/4, Mat4, linear algebra
└── platform_windows.odin — Win32 window, input, pixel blit
| Phím | Chức năng |
|---|---|
1–6 |
Debug mode: Color / Depth / Normal / UV / Barycentric / Wireframe |
WASD |
Di chuyển camera (orbit) |
Q / E |
Camera lên / xuống |
Chuột trái drag |
Xoay model |
Chuột trái click |
Inspect pixel (bary, UV, normal, depth) |
B |
Toggle backface culling |
Z |
Toggle z-buffer |
P |
Toggle perspective-correct interpolation |
L |
Toggle lighting |
N |
Toggle vertex normal arrows |
F |
Toggle wireframe overlay |
F1 / F2 |
Flat shading / Gouraud shading |
R |
Reset camera |
ESC |
Thoát |