Kinematic 0.5.0 is out. Modeling and sculpting in the viewport, a timeline on every graph, photo and sound editing. What's new
Kinematic / Developers

Developers.

Script it, extend it, write shaders and run it from the command line. Open to your own code, all the way down.

Python inside and outWGSL and GLSLA real CLI
doubler.py
import kinematic

@kinematic.ext.register_node
class Doubler(kinematic.node.PythonScriptNode):
    type_name = "Doubler"
    category = "Numeric Operations"
    description = "Multiplies the input by 2"

    inputs = [kinematic.node.PortDecl.channel_data("In_1").required()]
    outputs = [kinematic.node.PortDecl.channel_data("Out_1")]

    def execute(self, ctx):
        msg = ctx.pop_input(0)
        if msg is None:
            return
        ctx.post_output(0, kinematic.values.Value.channel_data([msg.as_float() * 2], 1))
the node, live on the canvas
the node, live on the canvas
Developers · Python

Script it

Build, change and query graphs from Python. Every call goes on the undo list, so one Cmd-Z undoes a script.

Build graphsEdit settingsWire nodesUndo groupsListen for changesStudio menusPanelsHeadless Python

kinematic.graph · kinematic.undo · kinematic.ui · kinematic.gpu

Try it: build a ring of spheres with a script →
build_mixer.py
import kinematic

with kinematic.undo.group("Build mixer"):
    g = kinematic.graph.current()
    mix = g.create_node("AudioMixer", position=(0, 0))
    gain = g.create_node("AudioGain", position=(200, 0))
    g.connect(mix, "Mixed", gain, "Audio")

gain.config["gain"] = "#time * 2"   # any value can be an expression
a Python node and the debugger
a Python node and the debugger
Developers · Your own nodes

Write your own nodes

A class with ports and an execute method becomes a node in the palette, like any built-in. It saves and reopens with the graph.

Python nodesData portsSettings with defaultsControl inputsGPU nodes from a shaderIcons and helpJavaScript nodes

PythonScriptNode · PythonExpressionNode · PythonGeneratorNode · JavascriptOperation

Your first node, in four steps →
doubler.py
import kinematic

@kinematic.ext.register_node
class Doubler(kinematic.node.PythonScriptNode):
    type_name = "Doubler"
    category = "Numeric Operations"
    description = "Multiplies the input by 2"

    inputs = [kinematic.node.PortDecl.channel_data("In_1").required()]
    outputs = [kinematic.node.PortDecl.channel_data("Out_1")]

    def execute(self, ctx):
        msg = ctx.pop_input(0)
        if msg is None:
            return
        ctx.post_output(0, kinematic.values.Value.channel_data([msg.as_float() * 2], 1))
start from a template
start from a template
Developers · Expressions

Type code into any param

Any setting can hold an expression or a line of Python instead of a number. It is read again every frame.

# expressions@ Python driversRead another node's valueChannels by nameTime and frameWorks in shader uniforms

NumericExpression · ChannelDataExpression · ImageSimpleExpression

Try it: spin a donut with one line of Python →
value boxes
gain      #time * 2
cutoff    #channel("pose", "left_wrist_x") * 4000
amount    #node_param("blur", "uniforms.radius")
label     @f"take {f}: {sin(t):.2f}"
a picture from one Python expression
a picture from one Python expression
Developers · Extensions

Package an extension

Bundle nodes, panels, menu commands, viewport tools and starter graphs into one folder. Build it, sign it, host your own repository.

NodesPanels and settingsOperators with a reportViewport tools and handlesImportersStarter graphsSigningYour own repository

kin_manifest.toml · kinematic.ext · .kinext

Your first extension, in four steps →
terminal
$ kinematic extension new stage-tools --template panel
$ kinematic extension test stage-tools
$ kinematic extension build stage-tools  # a .kinext anyone can install
$ kinematic extension index ./repo       # host your own repository
kin_manifest.toml
[extension]
id = "stage-tools"
name = "Stage Tools"
version = "0.1.0"
description = "Cue helpers for our touring rig"

[node_types]
register = ["nodes.smooth_value.SmoothValue"]
Developers · Shaders

Write shaders

WGSL or GLSL for pictures, materials, geometry and scans. Paste a Shadertoy. Errors point at your own line numbers.

WGSLGLSLShadertoy paste#include librariesUniforms with knobsMulti-pass and feedbackUp to 7 outputs32-bit float

ImageShader · ShaderMaterial · AttributeShader · GeometryComputeShader · 3DGeoSplatKernel

Try it: paste in a Shadertoy and give it sliders →
tonemap.wgsl
#include <lib/color>
@compute @workgroup_size(8, 8, 1)
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
    if (gid.x >= u32(KINOutputWidth()) ||
        gid.y >= u32(KINOutputHeight())) { return; }
    let p  = vec2<i32>(i32(gid.x), i32(gid.y));
    let uv = (vec2<f32>(p) + 0.5) / vec2<f32>(uKINOutputRes().xy);
    let hdr = KINInput(0u, uv);
    KINImageStoreOutput(0u, p, vec4<f32>(KINTonemapACES(hdr.rgb), hdr.a));
}
two shaders sharing one include
two shaders sharing one include
Developers · Command line

Run it from the command line

Run shows with no window, render to video, lint and test graphs in CI, and talk to a running show over the network.

runrenderlinttestbatchctlrepldevicesprobeprofiletracedocsstubs

kinematic --headless · kinematic --perform · kinematic --kiosk

Try it: render frames from the terminal →
terminal
$ kinematic run show.kin                  # no window, exits with the run's code
$ kinematic render scene.kin --out turntable.mp4
$ kinematic lint show.kin                 # catch wiring mistakes before the show
$ kinematic test show.kin                 # run it and check what came out
$ kinematic batch graphs/ out/            # a folder of graphs in one process
$ kinematic info 3DGeoFlipSimpleSolver    # ports and settings of any node
$ kinematic ctl tcp:10.0.0.5:9797 set blur.amount 3
$ kinematic repl                          # Python, no window
Developers · Protocols

Talk to anything

OSC, HTTP, WebSockets, webhooks, serial, MIDI, DMX and video between machines, all as nodes you can wire.

OSC and OSCQueryHTTP requestsWebSocket server and clientWebhooks in and outSerial portsMIDI 2.0Art-Net and sACNNDI and SyphonAbleton Live

OSCQueryExpose · HTTPRequest · WebSocketServerInterface · WebhooksServerInterface · SerialSendInterface

See every protocol on Works with →
OSCOSCQueryHTTPWebSocketWebhooksSerialMIDI 2.0Art-NetsACNNDISyphonRTMPLTC / MTCPSNStream Deck
Developers · Tools

Tools for the job

A Python editor with a debugger inside the app, type hints for your own editor, and a linter that knows every node.

Python editorBreakpoints on the graphType stubsLinterTest harnessProfilerGenerated API docs

kinematic stubs install · kinematic py-test · kinematic docs generate · kinematic profile

See the Python editor and debugger on the tour →
the Python editor with a script that builds a graph
the Python editor with a script that builds a graph
an extension panel
an extension panel
Start here

Your first extension, in four steps.

From an empty folder to something anyone can install.

Make the folderkinematic extension new writes a working extension with a node and a panel.
Write the nodeEdit the class in the Python editor. It reloads while the graph keeps running.
Test itkinematic extension test runs its own tests with no window.
Share itBuild a .kinext, sign it, and put it in a repository of your own.

Free and open. Yours to extend.

No account, no license key, no store between you and your users.

Download Kinematic 0.5.0