# Motion To Code

> Turn a prompt, an image or a reference video into a seamlessly looping GLSL shader, with a page that plays it live.


## Overview

- **Endpoint**: `https://fal.run/fal-ai/motion-to-code/glsl`
- **Model ID**: `fal-ai/motion-to-code/glsl`
- **Category**: video-to-video
- **Kind**: inference
**Description**: Writes one Shadertoy-style fragment shader (mainImage, GLSL ES 3.00, single pass, no textures) that loops seamlessly over the duration, renders it with WebGL2 and checks it against the reference. Without a video, MiniMax H3 Max first animates the prompt (text-to-video) or the image (image-to-video) into a reference clip, and that clip is rebuilt as code. Inputs: prompt (up to 4,000 characters), plus optionally video_url (a reference clip of 1 to 15 s, which sets the duration and the aspect ratio) or image_url (animated by H3 Max; its shape sets the aspect ratio). Give at least one; a video and an image together are refused. Options: duration 1-15 s (default 6, ignored with a video), aspect_ratio 16:9, 9:16 or 1:1 (default 16:9, ignored with a video or an image), refine_rounds 0 or 1 (default 1: the render is compared with the reference and the code fixed once). Output: code (the shader, ready for Shadertoy), html (a page that plays it), an MP4 preview, reference_video (the H3 Max clip, when one was made), a contact sheet of reference and render side by side, duration, rounds and timings. Billed per second of animation, 5 s minimum, 15 s maximum: $0.30 per second when H3 Max makes the reference clip, $0.20 per second from your own video (or when H3 Max can't make the clip).

**Tags**: code, glsl



## Pricing

Your request will cost **$0.30** per second of animation when MiniMax H3 Max animates your prompt or image first, or **$0.20** per second from your own video, with a 5-second minimum: a 6-second loop from a prompt costs **$1.80**, a 10-second clip rebuilt from your video **$2.00**.

For more details, see [fal.ai pricing](https://fal.ai/pricing).

## API Information

This model can be used via our HTTP API or more conveniently via our client libraries.
See the input and output schema below, as well as the usage examples.


### Input Schema

The API accepts the following input parameters:


- **`prompt`** (`string`, _optional_):
  What to build, or what to change from the reference. Without a video, MiniMax H3 Max first animates it as a reference clip. Default value: `""`
  - Default: `""`
  - Examples: "A blob squashes, hops and lands; the word LOOP pops in letter by letter."

- **`video_url`** (`string`, _optional_):
  Reference video to recreate, up to 15 s. Flat motion design works best.

- **`image_url`** (`string`, _optional_):
  Reference image: MiniMax H3 Max animates it, and the clip is rebuilt as code.

- **`audio_url`** (`string`, _optional_):
  Soundtrack for the loop, up to 15 MB. With a prompt or an image, MiniMax H3 Max makes its clip to this sound. Without it, the reference's own sound is kept.

- **`duration`** (`float`, _optional_):
  Loop length in seconds. Ignored with a video, which sets it. Default value: `6`
  - Default: `6`
  - Range: `1` to `15`

- **`aspect_ratio`** (`AspectRatioEnum`, _optional_):
  Stage shape. Ignored with a video or an image, which set it. Default value: `"16:9"`
  - Default: `"16:9"`
  - Options: `"16:9"`, `"9:16"`, `"1:1"`

- **`refine_rounds`** (`integer`, _optional_):
  Times the model compares its render with the reference and fixes it. Default value: `1`
  - Default: `1`
  - Range: `0` to `1`

- **`enable_safety_checker`** (`boolean`, _optional_):
   Default value: `true`
  - Default: `true`



**Required Parameters Example**:

```json
{}
```

**Full Example**:

```json
{
  "prompt": "A blob squashes, hops and lands; the word LOOP pops in letter by letter.",
  "duration": 6,
  "aspect_ratio": "16:9",
  "refine_rounds": 1,
  "enable_safety_checker": true
}
```


### Output Schema

The API returns the following output format:

- **`code`** (`string`, _required_):
  The generated code: the HTML page, or the GLSL shader.

- **`html`** (`string`, _required_):
  Self-contained page that plays the animation: save it as an .html file and open it in a browser.

- **`video`** (`VideoFile`, _required_):
  Preview rendered from the code, frame by frame.

- **`contact_sheet`** (`ImageFile`, _required_):
  Last check: reference and render side by side at the same times.

- **`reference_video`** (`VideoFile`, _optional_):
  The clip MiniMax H3 Max made from the prompt or image, which the code rebuilds.

- **`audio`** (`AudioFile`, _optional_):
  The loop's soundtrack, cut to its length: audio_url, or the reference's sound. It is also in the preview, and the page plays it after a click.

- **`duration`** (`float`, _required_):
  Loop length in seconds.

- **`rounds`** (`integer`, _required_):
  Generation passes run, first one included.

- **`timings`** (`Timings`, _required_):
  Seconds spent in each step.



**Example Response**:

```json
{
  "code": "",
  "html": "",
  "video": {
    "url": "",
    "content_type": "image/png",
    "file_name": "z9RV14K95DvU.png",
    "file_size": 4404019
  },
  "contact_sheet": {
    "url": "",
    "content_type": "image/png",
    "file_name": "z9RV14K95DvU.png",
    "file_size": 4404019
  }
}
```


## Usage Examples

### cURL

```bash
curl --request POST \
  --url https://fal.run/fal-ai/motion-to-code/glsl \
  --header "Authorization: Key $FAL_KEY" \
  --header "Content-Type: application/json" \
  --data '{}'
```

### Python

Ensure you have the Python client installed:

```bash
pip install fal-client
```

Then use the API client to make requests:

```python
import fal_client

def on_queue_update(update):
    if isinstance(update, fal_client.InProgress):
        for log in update.logs:
           print(log["message"])

result = fal_client.subscribe(
    "fal-ai/motion-to-code/glsl",
    arguments={},
    with_logs=True,
    on_queue_update=on_queue_update,
)
print(result)
```

### JavaScript

Ensure you have the JavaScript client installed:

```bash
npm install --save @fal-ai/client
```

Then use the API client to make requests:

```javascript
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/motion-to-code/glsl", {
  input: {},
  logs: true,
  onQueueUpdate: (update) => {
    if (update.status === "IN_PROGRESS") {
      update.logs.map((log) => log.message).forEach(console.log);
    }
  },
});
console.log(result.data);
console.log(result.requestId);
```


## Additional Resources

### Documentation

- [Model Playground](https://fal.ai/models/fal-ai/motion-to-code/glsl)
- [API Documentation](https://fal.ai/models/fal-ai/motion-to-code/glsl/api)
- [OpenAPI Schema](https://fal.ai/api/openapi/queue/openapi.json?endpoint_id=fal-ai/motion-to-code/glsl)

### fal.ai Platform

- [Platform Documentation](https://fal.ai/docs/documentation)
- [Python Client](https://fal.ai/docs/api-reference/client-libraries/python)
- [JavaScript Client](https://fal.ai/docs/api-reference/client-libraries/javascript)

### Other agent-readable surfaces

This file covers one model. To find anything else:

- [Platform overview](https://fal.ai/llms.txt): Entry points and representative endpoint IDs
- [Documentation index](https://fal.ai/docs/llms.txt): Every documentation page
- [Full documentation text](https://fal.ai/docs/llms-full.txt): The whole documentation inlined
- Any other model: `https://fal.ai/models/<endpoint-id>/llms.txt`
