Specimen / generative
Plasma (Sine Interference)
A flowing GPU plasma. Two sine-wave fields at slightly detuned scales beat against each other into shimmering moire fringes, a slow rotating domain warp bends the coordinates into liquid motion, and the result is mapped through a cyclic cosine palette. Self-contained and stateless - one GLSL TOP, no input, no feedback - so it drops in anywhere as a VJ loop, texture, or displacement source.
intermediate 5 operators
Node graph preview
Plasma (Sine Interference) graph
Show raw TDN YAML
Paste in TouchDesigner with Embody running.
format: tdn
version: '2.0'
build: null
generator: Embody/6.0.26
td_build: 099.2025.32820
source_file: Embody-6.26.toe
exported_at: '2026-06-13T15:59:04Z'
network_path: /specimen_lab/plasma_interference
options:
include_dat_content: true
include_storage: true
type_defaults:
textDAT:
parameters:
language: glsl
flags:
- viewer
size: [130, 90]
color: [0.67, 0.67, 0.67]
type: baseCOMP
custom_pars:
Plasma:
- name: Scale
style: Float
startSection: true
default: 6
min: 1.0
max: 20.0
clampMin: true
clampMax: true
normMin: 1.0
normMax: 20.0
help: Spatial frequency of the sine fields. Low = broad lava-lamp blobs; high = dense fine plasma.
- name: Speed
style: Float
default: 1
max: 4.0
clampMin: true
clampMax: true
normMax: 4.0
help: Animation speed. 1 = gentle flow; 0 freezes a still (the TOP keeps cooking, frame is identical).
- name: Warp
style: Float
default: 1.2
max: 3.0
clampMin: true
clampMax: true
normMax: 3.0
help: Domain-warp amount. 0 = flat sliding stripes; higher bends the coords into a flowing liquid swirl.
- name: Complexity
style: Float
label: Interference
default: 1
max: 2.0
clampMin: true
clampMax: true
normMax: 2.0
help: Detune between the two sine fields. 0 = one clean plasma; higher beats them into shimmering moire.
- name: Palette
style: Float
label: Palette Hue
startSection: true
clampMin: true
clampMax: true
help: Rotates the cyclic cosine palette through the full hue ring. Loops seamlessly 1.0 -> 0.0.
- name: Contrast
style: Float
default: 0.4
clampMin: true
clampMax: true
help: Palette saturation/contrast (onto a 0.6 base in the shader). Low = pastel; high = punchy neon.
color: [0.67, 0.67, 0.67]
operators:
- name: out1
type: outTOP
parameters:
label: =me.name
flags:
- viewer
position: [800, 0]
size: [130, 90]
color: [0.67, 0.67, 0.67]
inputs:
- glsl_plasma
- name: annotate1
type: annotateCOMP
parameters:
order: =me.digits or 0
layerzone: =0 if hasattr(me, 'EncloseOPs') and me.EncloseOPs else 1
sequences:
ext:
- object: op.TDAnnotate.mod.AnnotateExt.AnnotateExt(me)
promote: true
custom_pars:
Text:
- name: Titletext
style: Str
label: Title Text
startSection: true
default: Annotate
help: Text in the title bar.
value: Plasma - interfering sine fields + domain warp
- name: Titleheight
style: Int
label: Title Height
default: 30
clampMin: true
normMin: 5.0
normMax: 100.0
help: Height of the title bar. Title font height adjusts automatically to fill.
- name: Titlealign
style: Menu
label: Title Align
default: left
menuNames:
- left
- center
- right
menuLabels:
- Left
- Center
- Right
help: Alignment of title text.
- name: Bodytext
style: Str
label: Body Text
startSection: true
help: Text in the body area. Use an expression for newlines etc.
value: 'Two sine-wave fields at slightly detuned scales BEAT against each other -> moire fringes (the shimmer). A slow rotating domain warp bends the sample coords -> liquid flow. The summed field is folded cyclically into 0..1 and mapped through an Inigo-Quilez cosine palette (smooth hue cycling, never bands); a vignette frames it as a loop. All on the GPU in one glslTOP -- no input, no feedback, stateless and cheap. Params: Scale, Speed, Warp, Complexity (detune), Palette (hue), Contrast.'
- name: Bodyfontsize
style: Int
label: Body Font Size
default: 10
clampMin: true
normMin: 8.0
normMax: 100.0
help: Size of text in the body area.
- name: Bodylimitwidth
style: Toggle
label: Limit Body Text Width
help: Limit the width of the text area.
- name: Bodymaxwidth
style: Int
label: Max Body Text Width
default: 1000
clampMin: true
normMin: 100.0
normMax: 2000.0
help: Width limit that will cause wraparound or cut-off. Measured in Panel units.
Settings:
- name: Mode
style: Menu
default: comment
menuNames:
- comment
- networkbox
- annotate
menuLabels:
- Comment
- Network Box
- Annotate
help: 'Switch between Comment, Network Box, and Annotate Modes. '
value: annotate
- name: Smartquote
style: Toggle
label: Smart Quote
startSection: true
help: Converts quotes, ellipsis, and dashes to more typographically nice unicode versions.
- name: Bodywordwrap
style: Toggle
label: Body Word Wrap
default: true
help: Wrap body text when it extends past right bound.
- name: Backcolorr
style: RGBA
label: Back Color
startSection: true
default: 1
help: Background color base.
values: [0.13, 0.28, 0.32]
- name: Backcoloralpha
style: Float
label: Back Color Alpha
default: 1
clampMin: true
clampMax: true
help: Back color alpha.
- name: Opacity
style: Float
label: Annotate Opacity
default: 1
clampMin: true
clampMax: true
help: Opacity of the entire Annotate.
value: 0.25
OP Viewer:
- name: Opviewerdisplay
style: Toggle
label: Viewer Display
help: Turn the visibility of the viewer specified in the OP parameter below on or off.
- name: Opviewer
style: OP
label: OP
help: The operator whose viewer is displayed in the Annotate.
- name: Opviewerinteractive
style: Toggle
label: OP Viewer Interactive
help: Allow interaction with the OP viewer.
- name: Opvieweroversize
style: Menu
label: Size/Aspect Override
startSection: true
default: 'False'
menuNames:
- natural
- specify
- autofit
menuLabels:
- Natural
- Specify
- Auto-Fit
help: Use the Size/Aspect Override to control viewer's size in the background.
value: natural
- name: Opviewersize
style: WH
label: Size/Aspect
default: 800
clampMin: true
normMin: 1.0
normMax: 1000.0
help: Diplay viewer as-if it were being displayed at this resolution. This is particularly useful for zooming into operators that don't have a built-in resolution, like CHOPs, SOPs, and DATs.
- name: Opviewerscale
style: Float
label: Scale
startSection: true
default: 1
normMax: 2.0
help: Scale the viewer by this factor.
- name: Opviewerjustifyx
style: Float
label: Justify X
normMin: -1.0
help: Move the border of the viewer towards left edge of Annotate when negative or towards right edge when positive.
- name: Opviewerjustifyy
style: Float
label: Justify Y
normMin: -1.0
- name: Opviewerfillbodytitle
style: Toggle
label: Cover Body and Title
help: When True, allow viewer to display in the Annotate title area as well as body.
- name: Opviewerzoom
style: Float
label: OP Viewer Zoom
startSection: true
default: 1
min: 0.001
clampMin: true
normMin: 1.0
normMax: 5.0
help: Zoom the viewer by this scale factor without increasing the size of its display area in the Annotate.
- name: Opvieweroffsetx
style: XYZW
label: OP Viewer Offset
help: Offsets the displayed area within the viewer. Combined with OP Viewer Zoom, this lets you display a specific area of a viewer, such as a CHOP channel or table cell.
- name: Opviewerfillalpha
style: Float
label: Fill Alpha
startSection: true
default: 1
clampMin: true
clampMax: true
help: Alpha value of the background area in the OP Viewer.
About:
- name: Version
style: Str
startSection: true
default: '1.0'
readOnly: true
help: Annotate COMP default setup version.
- name: Help
style: Pulse
help: Click to open help page.
flags:
- display
position: [180, -220]
size: [820, 480]
color: [0.45, 0.45, 0.45]
palette_clone: true
- name: glsl_plasma
type: glslTOP
parameters:
pixeldat: glsl_plasma_pixel
computedat: glsl_plasma_compute
outputresolution: custom
resolutionw: 1280
resolutionh: 720
sequences:
vec:
- name: uParams
valuex: =parent().par.Scale.eval()
valuey: =parent().par.Warp.eval()
valuez: =parent().par.Complexity.eval()
valuew: =absTime.seconds*parent().par.Speed.eval()
- name: uPalette
valuex: =parent().par.Palette.eval()
valuey: =parent().par.Contrast.eval()
valuez: 0
valuew: 0
position: [400, 0]
size: [130, 90]
color: [0.67, 0.67, 0.67]
- name: glsl_plasma_info
type: infoDAT
parameters:
op: glsl_plasma
flags:
- viewer
position: [550, -150]
size: [130, 90]
color: [0.67, 0.67, 0.67]
dock: glsl_plasma
dat_read_only: true
- name: glsl_plasma_pixel
type: textDAT
parameters:
extension: frag
position: [400, -150]
dock: glsl_plasma
dat_content: |-
uniform vec4 uParams; // x=scale, y=warp, z=complexity(detune), w=time(=absTime*Speed)
uniform vec4 uPalette; // x=hue 0..1, y=contrast
out vec4 fragColor;
const float PI = 3.14159265;
// Inigo-Quilez cyclic cosine palette: smooth, loops in hue, never bands.
vec3 palette(float t, float hue, float contrast){
vec3 a = vec3(0.5);
vec3 b = vec3(0.5) * contrast;
vec3 c = vec3(1.0, 1.0, 1.0);
vec3 d = vec3(0.00, 0.33, 0.67) + hue; // hue rotates the phase offsets
return a + b * cos(6.28318 * (c * t + d));
}
// One animated sine field: a handful of moving plane-waves summed.
float field(vec2 p, float time, float freq){
float v = 0.0;
v += sin(p.x * freq + time);
v += sin(p.y * freq * 1.3 + time * 1.1);
v += sin((p.x + p.y) * freq * 0.7 + time * 0.9);
float cx = p.x + 0.5 * sin(time * 0.4);
float cy = p.y + 0.5 * cos(time * 0.35);
v += sin(sqrt(cx * cx + cy * cy) * freq * 1.6 + time * 1.3); // radial ripple, moving center
return v;
}
void main(){
float aspect = uTDOutputInfo.res.z / uTDOutputInfo.res.w; // output res = (1/w,1/h,w,h); zw = pixel dims
vec2 uv = vUV.st;
vec2 p = (uv - 0.5);
p.x *= aspect; // keep the plasma square on wide formats
float t = uParams.w;
float scale = max(0.5, uParams.x);
float warp = uParams.y;
float detune = uParams.z;
p *= scale;
// Domain warp: a slow rotating swirl bends the sample coords -> liquid flow.
vec2 w = vec2(
sin(p.y * 1.7 + t * 0.5),
cos(p.x * 1.5 - t * 0.45)
);
vec2 pw = p + warp * w;
// Two fields at slightly detuned scales BEAT against each other -> fringes.
float f1 = field(pw, t, 1.0);
float f2 = field(pw, t * 1.05, 1.0 + 0.25 * detune);
float v = (f1 + f2) * 0.25; // ~[-2,2]; folded cyclically into 0..1 below
v += 0.30 * detune * sin((f1 - f2) * PI); // explicit beat term -> visible moire shimmer
float tone = 0.5 + 0.5 * sin(v * PI); // fold into 0..1, smooth + cyclic
vec3 col = palette(tone, uPalette.x, 0.6 + uPalette.y);
float d = length(uv - 0.5); // gentle vignette: reads as a framed loop
col *= mix(1.0, 0.55, smoothstep(0.45, 0.95, d));
fragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
}
dat_content_format: text
- name: glsl_plasma_compute
type: textDAT
position: [250, -150]
dock: glsl_plasma
annotations:
- name: annotate1
mode: annotate
title: Plasma - interfering sine fields + domain warp
text: 'Two sine-wave fields at slightly detuned scales BEAT against each other -> moire fringes (the shimmer). A slow rotating domain warp bends the sample coords -> liquid flow. The summed field is folded cyclically into 0..1 and mapped through an Inigo-Quilez cosine palette (smooth hue cycling, never bands); a vignette frames it as a loop. All on the GPU in one glslTOP -- no input, no feedback, stateless and cheap. Params: Scale, Speed, Warp, Complexity (detune), Palette (hue), Contrast.'
position: [180, -220]
size: [820, 480]
color: [0.13, 0.28, 0.32]
opacity: 0.25