mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-30 01:41:43 +00:00
131 lines
3.5 KiB
Markdown
131 lines
3.5 KiB
Markdown
# Layout Compositor Reference
|
||
|
||
Patterns for building modular multi-panel grids — useful for HUD interfaces, data dashboards, and multi-source visual composites.
|
||
|
||
## Layout Approaches
|
||
|
||
| Approach | Best For | Notes |
|
||
|----------|----------|-------|
|
||
| `layoutTOP` | Fixed grid, quick setup | GPU, simple tiling |
|
||
| Container COMP + `overTOP` | Full control, mixed-size panels | More setup, very flexible |
|
||
| GLSL compositor | Procedural / BSP-style | Most powerful, more complex |
|
||
|
||
---
|
||
|
||
## layoutTOP
|
||
|
||
Built-in grid compositor — fastest path for uniform tile grids.
|
||
|
||
```python
|
||
layout = root.create(layoutTOP, 'layout1')
|
||
layout.par.resolutionw = 1920
|
||
layout.par.resolutionh = 1080
|
||
layout.par.cols = 3
|
||
layout.par.rows = 2
|
||
layout.par.gap = 4
|
||
```
|
||
|
||
Connect inputs (up to cols×rows):
|
||
```python
|
||
layout.inputConnectors[0].connect(op('panel_radar'))
|
||
layout.inputConnectors[1].connect(op('panel_wave'))
|
||
layout.inputConnectors[2].connect(op('panel_data'))
|
||
```
|
||
|
||
**Variable-width columns:** Not directly supported. Use overTOP approach for non-uniform grids.
|
||
|
||
---
|
||
|
||
## Container COMP Grid
|
||
|
||
Build each element as its own `containerCOMP`. Compose with `overTOP`:
|
||
|
||
```python
|
||
def create_panel(root, name, width, height, x=0, y=0):
|
||
panel = root.create(containerCOMP, name)
|
||
panel.par.w = width
|
||
panel.par.h = height
|
||
panel.viewer = True
|
||
return panel
|
||
|
||
# Composite with overTOP chain
|
||
over1 = root.create(overTOP, 'over1')
|
||
over1.inputConnectors[0].connect(panel_radar)
|
||
over1.inputConnectors[1].connect(panel_wave)
|
||
over1.par.topx2 = 0
|
||
over1.par.topy2 = 512
|
||
```
|
||
|
||
**Tip:** Use a `resolutionTOP` before each `overTOP` input if panels are different sizes.
|
||
|
||
---
|
||
|
||
## Panel Dividers (GLSL)
|
||
|
||
```glsl
|
||
out vec4 fragColor;
|
||
uniform vec2 uGridDivisions; // e.g. vec2(3, 2) for 3 cols, 2 rows
|
||
uniform float uLineWidth; // pixels
|
||
uniform vec4 uLineColor; // e.g. vec4(0.0, 1.0, 0.8, 0.6) for cyan
|
||
|
||
void main() {
|
||
vec2 res = uTDOutputInfo.res.zw;
|
||
vec2 uv = vUV.st;
|
||
vec4 bg = texture(sTD2DInputs[0], uv);
|
||
|
||
float lineW = uLineWidth / res.x;
|
||
float lineH = uLineWidth / res.y;
|
||
|
||
float vDiv = 0.0;
|
||
for (float i = 1.0; i < uGridDivisions.x; i++) {
|
||
float x = i / uGridDivisions.x;
|
||
vDiv = max(vDiv, step(abs(uv.x - x), lineW));
|
||
}
|
||
|
||
float hDiv = 0.0;
|
||
for (float i = 1.0; i < uGridDivisions.y; i++) {
|
||
float y = i / uGridDivisions.y;
|
||
hDiv = max(hDiv, step(abs(uv.y - y), lineH));
|
||
}
|
||
|
||
float line = max(vDiv, hDiv);
|
||
vec4 result = mix(bg, uLineColor, line * uLineColor.a);
|
||
fragColor = TDOutputSwizzle(result);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Element Library Pattern
|
||
|
||
Each visual element lives in its own `baseCOMP` as a reusable `.tox`:
|
||
|
||
### Standard Interface
|
||
```
|
||
inputs:
|
||
- in_audio (CHOP) — audio envelope / beat data
|
||
- in_data (CHOP) — optional data stream
|
||
- in_control (CHOP) — intensity, color, speed params
|
||
|
||
outputs:
|
||
- out_top (TOP) — rendered element
|
||
```
|
||
|
||
### Network Structure
|
||
```
|
||
/project1/
|
||
audio_bus/ ← all audio analysis (see audio-reactive.md)
|
||
elements/
|
||
elem_radar/ ← baseCOMP with out_top
|
||
elem_wave/
|
||
elem_data/
|
||
compositor/
|
||
layout1 ← layoutTOP or overTOP chain
|
||
dividers1 ← GLSL divider lines
|
||
postfx/ ← bloom → chrom → CRT stack (see postfx.md)
|
||
null_out ← final output
|
||
output/
|
||
windowCOMP ← full-screen output
|
||
```
|
||
|
||
**Key principle:** Elements don't know about each other. The compositor assembles them. Audio bus is referenced by all elements but lives separately.
|