Document new ant behaviors
This commit is contained in:
parent
451e187032
commit
2c303b61f2
2 changed files with 119 additions and 30 deletions
80
CLAUDE.md
80
CLAUDE.md
|
|
@ -1,38 +1,80 @@
|
|||
# ants-simulation
|
||||
|
||||
GPU-accelerated ant colony simulation. ants navigate via pheromone trails, all computed in GLSL fragment shaders rendered to offscreen textures.
|
||||
GPU-accelerated ant colony simulation. ants navigate via pheromone trails, all computed in GLSL fragment shaders rendered to offscreen textures. uses WebGL2 features (MRT, GLSL3).
|
||||
|
||||
## stack
|
||||
|
||||
- three.js — WebGL renderer, render targets, shader materials
|
||||
- three.js (0.173) — WebGL2 renderer, render targets, MRT, shader materials
|
||||
- lil-gui — runtime parameter tweaking
|
||||
- vite — dev server and build
|
||||
- biome — lint + format
|
||||
- bun — runtime, test runner, package manager
|
||||
- typescript
|
||||
- GLSL (raw .frag/.vert files loaded as strings via vite plugin)
|
||||
|
||||
## architecture
|
||||
|
||||
all simulation logic runs on the GPU via ping-pong render targets:
|
||||
|
||||
- `AntsComputeScene` — per-ant state (position, direction, scent storage) computed each frame
|
||||
- `AntsDiscretizeScene` — maps continuous ant positions to discrete world grid cells
|
||||
- `WorldComputeScene` — updates world pheromone grid based on ant deposits
|
||||
- `WorldBlurScene` — diffuses pheromones across neighboring cells
|
||||
- `DrawScene` — handles user painting (food, home, obstacles, erase)
|
||||
- `ScreenScene` — final composited output with camera controls
|
||||
|
||||
`Renderer.ts` orchestrates the render pass order and manages all WebGLRenderTargets.
|
||||
`Config.ts` holds simulation parameters exposed through lil-gui.
|
||||
|
||||
## commands
|
||||
|
||||
- `just check` — lint, typecheck, test (the gate for all work)
|
||||
- `bun run dev` — start dev server
|
||||
- `bun run build` — production build to `build/`
|
||||
- `bun run preview` — preview production build
|
||||
- `bun test` — run tests
|
||||
|
||||
## architecture
|
||||
|
||||
all simulation logic runs on the GPU via ping-pong render targets. no JS-side simulation loop — `Renderer.ts` orchestrates render passes and manages all WebGLRenderTargets.
|
||||
|
||||
### render pipeline (per frame)
|
||||
|
||||
1. `WorldBlurScene` — diffuse + decay pheromones (3 channels: toHome, toFood, repellent, each with independent blur radius and decay rate)
|
||||
2. clear `antsPresenceRenderTarget` (ant-ant spatial queries, stub)
|
||||
3. `AntsComputeScene` — per-ant state via MRT (writes 2 textures simultaneously)
|
||||
4. `AntsDiscretizeScene` — maps continuous ant positions to discrete world grid cells
|
||||
5. `WorldComputeScene` — merges ant deposits into world pheromone grid
|
||||
6. `ColonyStats` — CPU readback of ant texture, computes aggregate stats (foragerRatio), feeds back as uniforms
|
||||
7. `DrawScene` — user painting (food, home, obstacles, erase)
|
||||
8. `ScreenScene` — final composited output with camera controls
|
||||
|
||||
### GPU textures
|
||||
|
||||
**ant state** — 2 RGBA Float32 textures per ping-pong target (MRT, `count: 2`):
|
||||
- texture 0: `[pos.x, pos.y, angle, packed(storage << 1 | isCarrying)]`
|
||||
- texture 1: `[personality, cargoQuality, pathIntDx, pathIntDy]`
|
||||
|
||||
**world state** — RGBA Float32 (worldSize x worldSize):
|
||||
- R: packed cell metadata (bits 0-2: food/home/obstacle, bits 3-5: terrain type, bits 6-13: food quality)
|
||||
- G: scentToHome
|
||||
- B: scentToFood
|
||||
- A: repellent pheromone
|
||||
|
||||
**discrete ants** — RGBA UnsignedByte (worldSize x worldSize):
|
||||
- R: carrying ant scent deposit, G: non-carrying ant scent deposit, B: cell cleared flag, A: 1
|
||||
|
||||
**ant presence** — RGBA Float32 (worldSize x worldSize), cleared each frame. stub for future ant-ant spatial interaction.
|
||||
|
||||
### bit layout (world.R)
|
||||
|
||||
defined in `src/constants.ts`, shared between TS and GLSL via defines:
|
||||
- bits 0-2: cell flags (food, home, obstacle)
|
||||
- bits 3-5: terrain type (0-7, reserved for substrate-dependent decay)
|
||||
- bits 6-13: food quality (0-255, reserved for quality-dependent pheromone modulation)
|
||||
|
||||
### key files
|
||||
|
||||
- `src/Renderer.ts` — render target creation, pass orchestration, MRT setup, colony stats readback
|
||||
- `src/Config.ts` — simulation parameters (per-channel pheromone configs)
|
||||
- `src/constants.ts` — cell metadata bit layout (single source of truth for TS + GLSL)
|
||||
- `src/ColonyStats.ts` — CPU readback of ant texture for colony-level aggregate stats
|
||||
- `src/shaders/antsCompute.frag` — ant behavior + MRT output (2 render targets via layout qualifiers)
|
||||
- `src/shaders/worldBlur.frag` — per-channel pheromone diffusion/decay
|
||||
- `src/shaders/world.frag` — cell metadata bit preservation + pheromone merging
|
||||
|
||||
## planning docs
|
||||
|
||||
- `REALISM-IDEAS.md` — research-backed features for more realistic ant behavior
|
||||
- `INFRASTRUCTURE.md` — data structure analysis mapping features to GPU infrastructure layers
|
||||
|
||||
## shader files
|
||||
|
||||
in `src/shaders/`. each scene has a matched .vert/.frag pair. loaded as raw strings by the vite glsl plugin in `vite.config.ts`.
|
||||
in `src/shaders/`. each scene has a matched .vert/.frag pair. loaded as raw strings by the vite glsl plugin in `vite.config.ts`. all shaders use GLSL3 (`#version 300 es` via three.js `glslVersion: THREE.GLSL3`).
|
||||
|
||||
## textures
|
||||
|
||||
|
|
|
|||
69
README.md
69
README.md
|
|
@ -1,24 +1,71 @@
|
|||
# Ants simulation
|
||||
# ants-simulation
|
||||
|
||||
A simple ant colony GPU-accelerated simulation made with Three.js.
|
||||
GPU-accelerated ant colony simulation built with three.js and GLSL shaders. All simulation logic runs entirely on the GPU — no JavaScript-side physics loop.
|
||||
|
||||
**[Live demo](https://strandedkitty.github.io/ants-simulation/)**
|
||||
|
||||

|
||||
|
||||
## Rules
|
||||
## How it works
|
||||
|
||||
Ants can emit two types of pheromones: to-home pheromone and to-food pheromone. To-home pheromones are emitted by those ants searching for food and to-food pheromones are emitted by those carrying food. Ants searching for food are attracted to to-food pheromones, while ants searching for home are attracted to to-home pheromones.
|
||||
Ants emit two types of pheromones: **to-home** (left by ants searching for food) and **to-food** (left by ants carrying food). Ants searching for food follow to-food trails; ants carrying food follow to-home trails.
|
||||
|
||||
If an ant searching for food detects a food cell nearby, then it picks it up, and drops it after reaching home.
|
||||
Each ant carries a limited pheromone inventory. Picking up food or reaching home refills the inventory; each pheromone deposit drains it. This prevents ants that wandered too far from leaving misleading trails — their pheromone runs out, so their trails naturally fade.
|
||||
|
||||
If an ant senses the desirable pheromones nearby, then it turns to the direction of these pheromones, and if no pheromones are detected nearby or the ant can't decide at which direction pheromones are stronger, then is moves randomly.
|
||||
Pheromone trails diffuse across neighboring cells and decay over time. The simulation also supports a **repellent pheromone** channel (independent decay rate and diffusion radius) for future use.
|
||||
|
||||
It is important to prevent ants from following pheromone trails left by those ants who wandered too far from home or a food source. Each individual ant has an inventory for storing pheromones. Each time an ant leaves a pheromone marker anywhere on the map a small portion of the stored pheromones is used. And each time it picks up food or reaches home its inventory gets fully refilled.
|
||||
### Controls
|
||||
|
||||
- **Q** — paint home
|
||||
- **W** — paint food
|
||||
- **E** — paint obstacles
|
||||
- **R** — erase
|
||||
- **Mouse wheel** — zoom
|
||||
- **Click + drag** — pan
|
||||
|
||||
## Architecture
|
||||
|
||||
The simulation runs as a chain of GPU render passes using ping-pong render targets:
|
||||
|
||||
1. **Pheromone blur/decay** — diffuse and evaporate all pheromone channels
|
||||
2. **Ant compute** — update each ant's position, direction, and carrying state (MRT: writes primary + extended state simultaneously)
|
||||
3. **Discretize** — map continuous ant positions onto the world grid
|
||||
4. **World update** — merge ant deposits into the pheromone grid
|
||||
5. **Colony stats** — CPU readback of aggregate colony state (forager ratio)
|
||||
6. **Draw** — user painting input
|
||||
7. **Screen** — final composited output
|
||||
|
||||
### Per-ant state (2 textures via MRT)
|
||||
|
||||
| Texture | R | G | B | A |
|
||||
| -------- | ----------- | ------------ | --------- | --------------------------- |
|
||||
| Primary | pos.x | pos.y | angle | packed(storage, isCarrying) |
|
||||
| Extended | personality | cargoQuality | pathIntDx | pathIntDy |
|
||||
|
||||
### World state (RGBA Float32)
|
||||
|
||||
| Channel | Data |
|
||||
| ------- | ----------------------------------------------------------------------------- |
|
||||
| R | packed cell metadata (food/home/obstacle flags + terrain type + food quality) |
|
||||
| G | to-home pheromone |
|
||||
| B | to-food pheromone |
|
||||
| A | repellent pheromone |
|
||||
|
||||
## Development
|
||||
|
||||
Requires [bun](https://bun.sh).
|
||||
|
||||
```sh
|
||||
bun install
|
||||
bun run dev # start dev server
|
||||
just check # lint + typecheck + test
|
||||
```
|
||||
|
||||
Pheromone trails left by ants evaporate and diffuse over time.
|
||||
|
||||
## References
|
||||
|
||||
- https://softologyblog.wordpress.com/2020/03/21/ant-colony-simulations/
|
||||
- https://github.com/johnBuffer/AntSimulator
|
||||
- [Ant colony simulations (softology)](https://softologyblog.wordpress.com/2020/03/21/ant-colony-simulations/)
|
||||
- [AntSimulator (johnBuffer)](https://github.com/johnBuffer/AntSimulator)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
|
|
|||
Loading…
Reference in a new issue