mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-30 01:41:43 +00:00
183 lines
4.5 KiB
Markdown
183 lines
4.5 KiB
Markdown
# Post-FX Reference
|
||
|
||
Bloom, CRT scanlines, chromatic aberration, and feedback glow patterns for live visual work.
|
||
|
||
---
|
||
|
||
## Bloom
|
||
|
||
### Built-in Bloom TOP
|
||
|
||
TD's `bloomTOP` is the fastest path — GPU-accelerated, no shader needed.
|
||
|
||
```python
|
||
bloom = root.create(bloomTOP, 'bloom1')
|
||
bloom.par.threshold = 0.6 # Luminance threshold (0-1)
|
||
bloom.par.size = 0.03 # Spread radius (0-1)
|
||
bloom.par.strength = 1.5 # Bloom intensity
|
||
bloom.par.blendmode = 'add' # 'add' or 'screen'
|
||
```
|
||
|
||
**Audio reactive bloom:**
|
||
```python
|
||
bloom.par.strength.mode = ParMode.EXPRESSION
|
||
bloom.par.strength.expr = "op('audio_env')['envelope'][0] * 3.0 + 0.5"
|
||
```
|
||
|
||
### GLSL Bloom (More Control)
|
||
|
||
For multi-pass bloom with color tinting:
|
||
|
||
```glsl
|
||
// bloom_pixel.glsl — pass1: threshold + tint
|
||
out vec4 fragColor;
|
||
uniform float uThreshold;
|
||
uniform vec3 uBloomColor;
|
||
|
||
void main() {
|
||
vec4 col = texture(sTD2DInputs[0], vUV.st);
|
||
float luma = dot(col.rgb, vec3(0.299, 0.587, 0.114));
|
||
float bloom = max(0.0, luma - uThreshold);
|
||
fragColor = TDOutputSwizzle(vec4(col.rgb * bloom * uBloomColor, col.a));
|
||
}
|
||
```
|
||
|
||
Then blur with `blurTOP` (size ~0.02-0.05), composite back over source with `addTOP` or `compositeTOP` in Add mode.
|
||
|
||
---
|
||
|
||
## CRT / Scanlines
|
||
|
||
Pure GLSL — create a `glslTOP` and paste into its `_pixel` DAT.
|
||
|
||
```glsl
|
||
// crt_pixel.glsl
|
||
out vec4 fragColor;
|
||
uniform float uTime;
|
||
uniform float uScanlineIntensity; // 0.0 - 1.0, default 0.4
|
||
uniform float uCurvature; // 0.0 - 0.15, default 0.05
|
||
uniform float uVignette; // 0.0 - 1.0, default 0.8
|
||
|
||
vec2 curveUV(vec2 uv, float amount) {
|
||
uv = uv * 2.0 - 1.0;
|
||
vec2 offset = abs(uv.yx) / vec2(6.0, 4.0);
|
||
uv = uv + uv * offset * offset * amount;
|
||
return uv * 0.5 + 0.5;
|
||
}
|
||
|
||
void main() {
|
||
vec2 res = uTDOutputInfo.res.zw;
|
||
vec2 uv = vUV.st;
|
||
|
||
// CRT barrel distortion
|
||
uv = curveUV(uv, uCurvature * 10.0);
|
||
|
||
// Kill pixels outside curved screen
|
||
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
|
||
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||
return;
|
||
}
|
||
|
||
vec4 col = texture(sTD2DInputs[0], uv);
|
||
|
||
// Scanlines
|
||
float scanline = sin(uv.y * res.y * 3.14159) * 0.5 + 0.5;
|
||
col.rgb *= mix(1.0, scanline, uScanlineIntensity);
|
||
|
||
// Horizontal noise flicker
|
||
float flicker = TDSimplexNoise(vec2(uv.y * 100.0, uTime * 8.0)) * 0.03;
|
||
col.rgb += flicker;
|
||
|
||
// Vignette
|
||
vec2 vig = uv * (1.0 - uv.yx);
|
||
float v = pow(vig.x * vig.y * 15.0, uVignette);
|
||
col.rgb *= v;
|
||
|
||
fragColor = TDOutputSwizzle(col);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Chromatic Aberration
|
||
|
||
Splits RGB channels and offsets them along screen axes.
|
||
|
||
```glsl
|
||
out vec4 fragColor;
|
||
uniform float uAmount; // 0.001 - 0.02, default 0.006
|
||
|
||
void main() {
|
||
vec2 uv = vUV.st;
|
||
vec2 dir = uv - 0.5;
|
||
|
||
float r = texture(sTD2DInputs[0], uv + dir * uAmount).r;
|
||
float g = texture(sTD2DInputs[0], uv).g;
|
||
float b = texture(sTD2DInputs[0], uv - dir * uAmount).b;
|
||
float a = texture(sTD2DInputs[0], uv).a;
|
||
|
||
fragColor = TDOutputSwizzle(vec4(r, g, b, a));
|
||
}
|
||
```
|
||
|
||
**Audio-reactive variant** — spike aberration on beats:
|
||
```glsl
|
||
uniform float uBeat;
|
||
void main() {
|
||
vec2 uv = vUV.st;
|
||
vec2 dir = uv - 0.5;
|
||
float amount = uAmount + uBeat * 0.04;
|
||
float r = texture(sTD2DInputs[0], uv + dir * amount * 1.2).r;
|
||
float g = texture(sTD2DInputs[0], uv).g;
|
||
float b = texture(sTD2DInputs[0], uv - dir * amount * 0.8).b;
|
||
fragColor = TDOutputSwizzle(vec4(r, g, b, 1.0));
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Feedback Glow
|
||
|
||
Warm persistent trails for glow effects.
|
||
|
||
```glsl
|
||
out vec4 fragColor;
|
||
uniform float uDecay; // 0.92 - 0.98 for slow trails
|
||
uniform vec3 uGlowColor; // tint accumulated feedback
|
||
|
||
void main() {
|
||
vec2 uv = vUV.st;
|
||
vec4 prev = texture(sTD2DInputs[0], uv); // feedback input
|
||
vec4 curr = texture(sTD2DInputs[1], uv); // current frame
|
||
|
||
vec3 glow = prev.rgb * uDecay * uGlowColor;
|
||
vec3 result = max(glow, curr.rgb);
|
||
|
||
fragColor = TDOutputSwizzle(vec4(result, 1.0));
|
||
}
|
||
```
|
||
|
||
**Tips:**
|
||
- `uDecay = 0.95` → medium trail
|
||
- `uDecay = 0.98` → long comet tail
|
||
- Set `glslTOP` format to `rgba16float` for smooth gradients
|
||
|
||
---
|
||
|
||
## Full Post-FX Stack
|
||
|
||
Recommended order:
|
||
|
||
```
|
||
[scene / composite]
|
||
↓
|
||
bloomTOP ← luminance threshold bloom
|
||
↓
|
||
glslTOP (chrom) ← chromatic aberration
|
||
↓
|
||
glslTOP (crt) ← scanlines + barrel distortion + vignette
|
||
↓
|
||
null_out ← final output
|
||
```
|
||
|
||
**Performance note:** Each glslTOP is a full GPU pass. For 1920×1080 at 60fps this stack is comfortably real-time. For 4K, consider downsampling bloom input with `resolutionTOP` first.
|