feat: 3D rendering with OBJ support and Utah Teapot example
- Dominant language
- Clojure
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Goal
Extend the engine from 2D to 3D rendering. Add OBJ mesh loading, a depth buffer, a 3D camera with a perspective projection, and demonstrate it with the classic Utah Teapot.
## Engine work
### Depth buffer
- Add depth image + `VkImageView` to the renderer (`spock.renderer.vulkan`)
- Enable depth testing in the pipeline builder (`VkPipelineDepthStencilStateCreateInfo`)
- Add `pipeline/depth-test` option: `(pipeline/depth-test cfg true)`
### Camera / UBO
- `spock.camera` — perspective camera record: position, target, fov, near, far
- `camera->matrix` — returns a 4×4 view-projection matrix (column-major, Vulkan NDC)
- Upload per-frame via a uniform buffer object (UBO) or push constants (64-byte push constant block fits a mat4 + model mat4 as two separate draws)
### Vertex format
- 3D vertices: `vec3 position`, `vec3 normal`, `vec2 uv` — 32 bytes per vertex
- New `VkVertexInputAttributeDescription` entries in pipeline builder
### OBJ loader — `spock.obj`
- Parse Wavefront OBJ: `v` (vertices), `vn` (normals), `vt` (UVs), `f` (faces, triangulate quads)
- Returns `{:vertices FloatBuffer :indices IntBuffer :vertex-count int}`
- Index buffer support in renderer (currently only vertex buffers)
### `:mesh` renderable type (spock.edn)
```edn
{:type :mesh
:file "examples/teapot/teapot.obj"
:color [0.8 0.6 0.3 1.0]}
```
- Loads OBJ, uploads vertex + index buffers
- Per-instance push constants: 4×4 model matrix + color
### Shaders
- `src/shaders/mesh.vert` — `vec3 pos`, `vec3 normal` in; push constant mat4 model + mat4 view-proj; Phong lighting
- `src/shaders/mesh.frag` — simple diffuse + ambient
## Utah Teapot example
```
examples/teapot/
game.edn
settings.edn
teapot.obj ← Newell teapot OBJ (public domain)
scenes/teapot.edn
scripts/teapot.clj ← rotate teapot over time, orbit camera
```
Makefile targets: `shaders/mesh`, `run/teapot`, `teapot`
## Depends on
- #49 (image loading) — optional, needed for textured meshes; mesh can ship with flat color first
- Depth buffer is a prerequisite for correct 3D rendering
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading spock.renderer.vulkan, the pipeline builder, spock.camera, and spock.obj to map the existing renderer and buffer abstractions. Then inspect src/shaders/mesh.vert, src/shaders/mesh.frag, and the examples/teapot files. Done means the depth-tested 3D mesh path, OBJ support, shaders, and teapot targets work together as described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clojure
- Domain
- computer-graphics
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100