Using Alma to create generative graphics
Tags: webdev
Published: 2023-11-28 20:19:22

**Written by [Emmanuel Odioko](https://blog.logrocket.com/author/emmanuelodioko/)✏️**

Before the introduction of generative graphics tools, creating detailed designs was a time-consuming and manually intensive process. This was especially true for designs involving complex patterns. Generative graphics tools introduced automation and algorithmic techniques into the creative process, empowering artists and developers to push their creative boundaries. 

In this tutorial, we’ll introduce Alma, a new generative graphic platform, and discuss its features and capabilities. We’ll also demonstrate how easy it is to use Alma’s interactive playground to create generative graphics.

### Prerequisites

To get the most value from this tutorial, you should have the following:

*   Familiarity with the concept of generative graphics
*   Basic knowledge of node-based programming
*   Basic knowledge of interactive design

## What are generative graphics?

The concept of generative art and graphics has roots in the early days of computer programming and digital art. Artists and programmers have been experimenting with algorithmic and generative techniques since the mid-20th century. 

One of the pioneering figures in generative art is [Georg Nees](https://en.wikipedia.org/wiki/Georg_Nees), a German artist who, in the 1960s, used algorithms to create artwork. Subsequently, other artists and researchers, such as [Frieder Nake](https://en.wikipedia.org/wiki/Frieder_Nake) and [Vera Molnár](https://en.wikipedia.org/wiki/Vera_Moln%C3%A1r), contributed to the development of generative art and graphics.

## What are generative graphic tools?

Generative graphics tools are software applications or programming frameworks that enable visual content creation through algorithms. These algorithms are used to generate digital art, interactive installations, data visualization, and creative coding. 

Here’s an analogy that may help explain this concept further: imagine that generative graphic tools are automated, self-playing instruments. Composers create the algorithms that define the rules and patterns. The instruments, guided by the algorithms and instructions, can produce relaxing melodies, harmonies, and rhythms without direct human input for each note. 

Developers are like the composers in this analogy, defining the algorithms and instructions. The generative tool interprets these algorithms to create visual compositions, just as the self-playing instruments interpret musical scores to produce music.

## Getting to know Alma

[Alma](https://www.alma.sh) is a unique platform that harnesses the power of generative graphics, allowing users to create beautiful visual effects and graphics through a node-based system. Alma is comparable to [Blender's node editor,](https://www.blender.org) a popular tool for 3D artists and designers. Similar to Blender, Alma's approach is centered around nodes, connections, and code nodes, offering a versatile toolset for crafting dynamic visual experiences. 

Alma finds utility across various creative domains. Whether you're an artist, a designer, or a developer, Alma can serve your needs in different ways. Here are some potential use cases for Alma:

*   **Website graphics**: Designers and developers can leverage Alma to create captivating graphics for websites, enhancing user engagement and visual appeal
*   **Artistic expression**: Artists can use Alma to experiment with generative graphics, bringing their visions to life through code and creative node-based interactions
*   **Interactive installations**: Developers can use Alma to create interactive installations for events, or digital experiences, adding a dynamic and engaging element to their projects
*   **Educational purposes**: Educational institutions may find Alma valuable for teaching students about generative graphics, creative coding, and visual effects.

> **N.B.**, as of this writing, Alma is still in the alpha stage, so there may still be some challenges associated with implementations

## Introducing Alma’s playground

[Alma's playground](https://www.alma.sh/playground) is where our creative journey begins. Let’s take a look to better understand how we can use this tool to create our own generative graphics. The playground comprises several essential components, each serving a distinct role in the generative graphics creation process.

### Nodes

Nodes are the fundamental building blocks within Alma's circuit. They represent various operations, such as trigonometry logic, texture sampling, color manipulation, and lighting calculations: ![Alma Nodes](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-nodes.png) These nodes have input and output ports, allowing users to create complex networks of operations: ![Alma Nodes Input Output Ports](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-nodes-input-output-ports.png) In the above example, we can see two nodes with their inputs and outputs. First, there’s a `VECTOR` `4` node that takes in four float inputs (the `F` stands for float) and outputs a four-component vector (`VEC4`). 

We connect the `VEC4` output to the `VEC4 COLOR` input of the second node, `WEBGL CONTEXT`, which is the root node of the graph that injects its color into the renderer.

### Connections

Connections serve as the pathways for logic and data flow throughout our circuit. They ensure that data moves seamlessly between nodes, enforcing a strict type system to maintain consistency. 

Here’s the connection from our previous example: ![Alma Nodes Connections](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-node-connections.png)

### Code nodes

The [GLSL (OpenGL Shading Language)](https://en.wikipedia.org/wiki/OpenGL_Shading_Language) node is an option for those who want to implement complex logic quickly. Users can input a GLSL function, which Alma automatically converts into a node that’s compatible with other nodes in the circuit. 

This is a really handy feature. A couple of Code nodes, like `CREATION`, are already available from the Alma playground: ![Alma Code Node Creation](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-code-node-creation.png) In order to see the code, we can click the **<>** icon in the GLSL function node: ![Alma Creation Effect GLSL Function Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-creation-effect-glsl-fucntion-node.png)

### Toolbar

The toolbar provides convenient utilities to enhance user experience. It includes options for viewing the final GLSL code, accessing examples for inspiration, adding new nodes to our circuit, importing and exporting serialized circuits, and enabling a fullscreen mode for an immersive experience: ![Alma Playground Toolbar](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-playground-toolbar.png)

### Effects

Alma offers a collection of prebuilt graphic effects in its playground that we can modify and experiment with. Some examples include `GRADIENT`, `NOISE`, `REPETITION`, and `CREATION`. These serve as starting points for our creative projects: ![Alma Playground Effects](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-playground-effects.png)

## Creating a basic noise effect graphic

Let’s use Alma’s playground to create a simple noise effect graphic. In this step-by-step guide, we’ll introduce the interface, demonstrate how to manipulate nodes and connections, and provide insights for creating visually appealing generative graphics.

### Enter the playground

First, let’s visit [Alma’s playground](https://www.alma.sh/playground). There’s a short tutorial there that serves as a basic introduction the playground: ![Enter Alma Playground Generative Graphics](https://blog.logrocket.com/wp-content/uploads/2023/11/enter-alma-playground-generative-graphics.png) Now, let’s click **Next** to enter the playground. This opens up an example playground that we can play around with to get a feel for the components and how they work: ![Alma Generative Graphics Tool Playground](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-generative-graphics-tool-playground.png) For the purposes of this tutorial, we’ll create a new playground interface.

### Import the WebGL Context node

The WebGL Context node is required to render graphics. It’s currently a bit tricky to add this node using the toolbar, so instead we’ll just import a circuit containing the node. 

A circuit is basically a JSON file that generates the nodes and connections of a playground. To import a circuit, we click the **IMPORT/EXPORT** button, represented by a save icon (the fourth icon from the left in the below toolbar: ![Alma Input Circuit WebGL Context Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-import-circuit-webgl-context-node.png) Once the text field is open, we’ll enter the following code:

```json
{
    "id": "946cbf0c-555c-4a23-8871-153033dcb299",
    "name": "Alma WebGL Starter",
    "nodes": [
        [
            "dfb2ecbb-0845-471d-b910-2fdaf575c26b",
            {
                "id": "dfb2ecbb-0845-471d-b910-2fdaf575c26b",
                "name": "WebGL Context",
                "type": "WEBGL_CONTEXT",
                "data": {
                    "position": {
                        "x": -388,
                        "y": 263
                    }
                },
                "inputs": {
                    "color": {
                        "id": "22370f15-7e0d-4529-9444-f6763afff4a5",
                        "name": "Color",
                        "type": "vec4",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "vec4",
                            "val": [
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 1
                                }
                            ]
                        },
                        "value": {
                            "tag": "lit",
                            "type": "vec4",
                            "val": [
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                }
                            ]
                        }
                    }
                },
                "outputs": {}
            }
        ]
    ],
    "connections": []
}
```

Now, we should have something like this in the playground: ![WebGL Context Node Alma Playground](https://blog.logrocket.com/wp-content/uploads/2023/11/webgl-context-node-alma-playground.png)

## Creating a static noise effect

To create a static noise effect, we’ll need three additional nodes:

*   UV node
*   Random node (a custom GLSL Code node)
*   Vector 4 node

### Create the UV node

To add the UV node, we click the **+** button in the toolbar, or right-click anywhere on the circuit canvas, and then select **NEW NODE > ACCESSORS > UV**: ![Alma Creating UV Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-creating-uv-node.png) The UV Node has three Vector 2 (`V2`) outputs; we’re interested in the `ASPECT CORRECTED` output. This is where the random node comes into play.

### Create a random GLSL Code node

Next, let’s click the **+NEW NODE**, or right-click on the canvas, to create a new node. Then, we’ll select **NEW NODE > COMMON > GLSL**: ![Alma Creating Random GLSL Code Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-creating-random-glsl-code-node.png) Now, we’ll enter the following code:

```json
float random(vec2 p) {
    vec2 K1 = vec2(
        23.14069263277926, // e^pi (Gelfond's constant)
        2.665144142690225 // 2^sqrt(2) (Gelfond–Schneider constant)
    );
    return fract( cos( dot(p,K1) ) * 12345.6789 );
}
```

![Alma Random Float Code](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-random-float-code.png) At this point, the playground should look like this: ![Alma Node Vector 2 Input Float Output](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-node-vector-2-input-float-output.png) This node takes a Vector 2 (`VEC2`) input and outputs a float (`F`).

### Add a Vector 4 node

In order to display graphics, we’ll need to provide a Vector 4 input for the WebGL Context node. Let’s click the **+** button in the toolbar, or right-click on the canvas. Then, we’ll select **NEW NODE > VECTOR > VECTOR 4**: ![Alma Adding Vector 4 Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-adding-vector-4-node.png) Once the node has been created, we can enter the random float (`F`) output from the `RANDOM` node into the `VECTOR 4` node, like so: ![Alma Adding Random Float To Vector 4 Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-adding-random-float-to-vector-4-node.png) This will produce the noise effect: ![Noise Effect Alma Generative Graphics Tool](https://blog.logrocket.com/wp-content/uploads/2023/11/noise-effect-alma-gnerative-graphics-tool.png) Here’s the generated code for the `Static Noise effect` graphic:

```json
{
    "id": "946cbf0c-555c-4a23-8871-153033dcb299",
    "name": "Static Noise effect",
    "nodes": [
        [
            "dfb2ecbb-0845-471d-b910-2fdaf575c26b",
            {
                "id": "dfb2ecbb-0845-471d-b910-2fdaf575c26b",
                "name": "WebGL Context",
                "type": "WEBGL_CONTEXT",
                "data": {
                    "position": {
                        "x": -197,
                        "y": 422
                    }
                },
                "inputs": {
                    "color": {
                        "id": "22370f15-7e0d-4529-9444-f6763afff4a5",
                        "name": "Color",
                        "type": "vec4",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "vec4",
                            "val": [
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 1
                                }
                            ]
                        }
                    }
                },
                "outputs": {}
            }
        ],
        [
            "d0b1e7a5-c0d9-4665-9a7f-177b4a926bd4",
            {
                "id": "d0b1e7a5-c0d9-4665-9a7f-177b4a926bd4",
                "name": "UV",
                "type": "UV",
                "data": {
                    "position": {
                        "x": -1055,
                        "y": 532
                    }
                },
                "inputs": {},
                "outputs": {
                    "aspectCorrected": {
                        "id": "1876fc2e-5876-4739-8d4d-065588e7344e",
                        "name": "Aspect Corrected",
                        "type": "vec2"
                    },
                    "uv": {
                        "id": "4aa3fb2c-cef1-4cf0-848c-dce738555fea",
                        "name": "UV",
                        "type": "vec2"
                    },
                    "fragCoord": {
                        "id": "8412d3a3-c97e-403a-b845-287342a274d7",
                        "name": "Frag Coord",
                        "type": "vec4"
                    }
                }
            }
        ],
        [
            "a6b8018e-00b9-4ea0-acbb-f497b21806a9",
            {
                "id": "a6b8018e-00b9-4ea0-acbb-f497b21806a9",
                "name": "Random",
                "type": "GLSL",
                "data": {
                    "glsl": "float random(vec2 p) {n    vec2 K1 = vec2(n        23.14069263277926, // e^pi (Gelfond's constant)n        2.665144142690225 // 2^sqrt(2) (Gelfond–Schneider constant)n    );nn    return fract( cos( dot(p,K1) ) * 12345.6789 );n}",
                    "position": {
                        "x": -773,
                        "y": 689
                    }
                },
                "inputs": {
                    "p": {
                        "id": "c38394cc-3175-4e27-b3f9-f5c5ac24b202",
                        "name": "p",
                        "type": "vec2",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "vec2",
                            "val": [
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                }
                            ]
                        }
                    }
                },
                "outputs": {
                    "output": {
                        "id": "420b0fa1-3edd-4892-a1b7-dc0dec3467ed",
                        "name": "Output",
                        "type": "float"
                    }
                }
            }
        ],
        [
            "76d22e0f-f9b4-48db-831b-c084bad5129a",
            {
                "id": "76d22e0f-f9b4-48db-831b-c084bad5129a",
                "name": "Vector 4",
                "type": "VECTOR_4",
                "data": {
                    "position": {
                        "x": -483,
                        "y": 651
                    }
                },
                "inputs": {
                    "x": {
                        "id": "ebb5d644-5865-4f47-9334-c67fae2aea61",
                        "name": "X",
                        "type": "float",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "float",
                            "val": 0
                        }
                    },
                    "y": {
                        "id": "605b83ac-83d0-4256-b1cf-d3c2ed9e6d6f",
                        "name": "Y",
                        "type": "float",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "float",
                            "val": 0
                        }
                    },
                    "z": {
                        "id": "93ccd2d6-fb68-47ff-8e6e-c3591426df54",
                        "name": "Z",
                        "type": "float",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "float",
                            "val": 0
                        }
                    },
                    "w": {
                        "id": "8ab84ce4-0373-4dfa-9afb-040debd5f198",
                        "name": "W",
                        "type": "float",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "float",
                            "val": 1
                        }
                    }
                },
                "outputs": {
                    "vector4": {
                        "id": "0808e28c-f00f-43d7-becb-bc72dc5b03b9",
                        "name": "Vector 4",
                        "type": "vec4"
                    }
                }
            }
        ]
    ],
    "connections": [
        [
            "01078152-6cf7-4c6f-8b28-3ea800462c18",
            {
                "id": "01078152-6cf7-4c6f-8b28-3ea800462c18",
                "from": "1876fc2e-5876-4739-8d4d-065588e7344e",
                "to": "c38394cc-3175-4e27-b3f9-f5c5ac24b202"
            }
        ],
        [
            "5e230d0d-ec71-481b-9c73-3fb90b199ff1",
            {
                "id": "5e230d0d-ec71-481b-9c73-3fb90b199ff1",
                "from": "420b0fa1-3edd-4892-a1b7-dc0dec3467ed",
                "to": "ebb5d644-5865-4f47-9334-c67fae2aea61"
            }
        ],
        [
            "06fbd536-8aad-457c-a77e-75b9e166582c",
            {
                "id": "06fbd536-8aad-457c-a77e-75b9e166582c",
                "from": "420b0fa1-3edd-4892-a1b7-dc0dec3467ed",
                "to": "605b83ac-83d0-4256-b1cf-d3c2ed9e6d6f"
            }
        ],
        [
            "9d4cc697-8807-4478-9f7d-d721d6073401",
            {
                "id": "9d4cc697-8807-4478-9f7d-d721d6073401",
                "from": "420b0fa1-3edd-4892-a1b7-dc0dec3467ed",
                "to": "93ccd2d6-fb68-47ff-8e6e-c3591426df54"
            }
        ],
        [
            "3b1bd33c-bd6c-4d6d-bb2f-c03e19915467",
            {
                "id": "3b1bd33c-bd6c-4d6d-bb2f-c03e19915467",
                "from": "420b0fa1-3edd-4892-a1b7-dc0dec3467ed",
                "to": "8ab84ce4-0373-4dfa-9afb-040debd5f198"
            }
        ],
        [
            "402faf84-44b2-45d7-bcbf-b83cd845168d",
            {
                "id": "402faf84-44b2-45d7-bcbf-b83cd845168d",
                "from": "0808e28c-f00f-43d7-becb-bc72dc5b03b9",
                "to": "22370f15-7e0d-4529-9444-f6763afff4a5"
            }
        ]
    ]
}
```

## Creating a gradient effect

Let’s demonstrate how to use Alma’s playground to create a gradient effect. To start, we’ll set up a blank playground by removing existing nodes or by importing a circuit. 

To create the gradient effect, we’ll need four nodes:

*   WebGL Context node
*   UV node
*   Swizzle node
*   Vector 4 node

### Import the WebGL Context node

The WebGL Context node is required to render the graphics. We’ll import the circuit as we did earlier in this tutorial by clicking the **IMPORT/EXPORT** button, represented by a save icon: ![Alma Importing WebGL Context Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-importing-webgl-context-node.png) Once the text field is open, we’ll enter the following code:

```json
{
  "id": "946cbf0c-555c-4a23-8871-153033dcb299",
    "name": "Alma WebGL Starter",
    "nodes": [
        [
            "dfb2ecbb-0845-471d-b910-2fdaf575c26b",
            {
                "id": "dfb2ecbb-0845-471d-b910-2fdaf575c26b",
                "name": "WebGL Context",
                "type": "WEBGL_CONTEXT",
                "data": {
                    "position": {
                        "x": -388,
                        "y": 263
                    }
                },
                "inputs": {
                    "color": {
                        "id": "22370f15-7e0d-4529-9444-f6763afff4a5",
                        "name": "Color",
                        "type": "vec4",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "vec4",
                            "val": [
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 1
                                }
                            ]
                        },
                        "value": {
                            "tag": "lit",
                            "type": "vec4",
                            "val": [
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                }
                            ]
                        }
                    }
                },
                "outputs": {}
            }
        ]
    ],
    "connections": []
}
```

The playground should look like this: ![Alma Playground WebGL Context Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-playground-webgl-context-node.png) Next, we’ll add a couple of nodes to create a gradient effect.

### Add the UV node

To add the UV node, let’s click the **+** button in the toolbar, or right-click anywhere on the circuit canvas, and select **NEW NODE > ACCESSORS > UV**: ![Alma Adding UV Accessors Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-adding-uv-accessors-node.png)

### Add a Swizzle node

Next, we’ll add a Swizzle node that destructs a vector and returns its individual components. Then, we’ll click the **+** button in the toolbar, or right-click anywhere on the circuit canvas, and select **NEW NODE > VECTOR > SWIZZLE**: ![Alma Swizzle Vector Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-swizzle-vecor-node.png)

### Add a Vector 4 node

Now, we’ll add a Vector 4 node that takes in four float values and outputs a four-component vector. We’ll click the **+** button in the toolbar, or right-click anywhere on the circuit canvas, and select **NEW NODE > VECTOR > VECTOR 4**: ![Alma Adding New Vector 4 Node](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-adding-new-vector-4-node.png)

### Connecting the nodes

Now, let’s connect our nodes by following these steps:

1.  Connect the `UV` output of the `UV` node to the `SWIZZLE` vector input
2.  Connect the `X` and `Y` float output of the `SWIZZLE` node to the `X` and `Y` input of the `VECTOR` `4` node
3.  Connect the `VECTOR` `4` output to the `COLOR` input of the `WEBGL CONTEXT` node

We should have something like this: ![Alma Connecting Nodes Gradient Effect](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-connecting-nodes-gradient-effect.png)

### Animating the gradient

We can animate the gradient by adding a `TIME` node. Let’s click the **+** button in the toolbar, or right-click anywhere on the circuit canvas, and select **NEW NODE > ACCESSORS > TIME**: ![Alma Time Node Animate Gradient](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-time-node-animate-gradient.png) Next, we’ll add a `SINE` node which returns the sine of the given input. Click the **+** button in the toolbar, or right-click anywhere on the circuit canvas, and select **NEW NODE > TRIGONOMETRY > SINE**: ![Alma Trigonometry Sine Node Animate Gradient](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-trigonometry-sine-node-animate-gradient.png) Now, we simply connect the `TIME` output to the `SINE` input and the `SINE` output to one of the `VECTOR` `4` inputs like so: ![Alma Connect Time Sine Nodes Animation](https://blog.logrocket.com/wp-content/uploads/2023/11/alma-connect-time-sine-nodes-animation.png) Here’s the resulting gradient: ![Animated Gradient Created Alma Generative Graphics](https://blog.logrocket.com/wp-content/uploads/2023/11/animated-gradient-created-alma-generative-graphics.gif) Here’s the output code:

```json
{
    "id": "946cbf0c-555c-4a23-8871-153033dcb299",
    "name": "Alma Gradient",
    "nodes": [
        [
            "dfb2ecbb-0845-471d-b910-2fdaf575c26b",
            {
                "id": "dfb2ecbb-0845-471d-b910-2fdaf575c26b",
                "name": "WebGL Context",
                "type": "WEBGL_CONTEXT",
                "data": {
                    "position": {
                        "x": 345,
                        "y": 243
                    }
                },
                "inputs": {
                    "color": {
                        "id": "22370f15-7e0d-4529-9444-f6763afff4a5",
                        "name": "Color",
                        "type": "vec4",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "vec4",
                            "val": [
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 1
                                }
                            ]
                        }
                    }
                },
                "outputs": {}
            }
        ],
        [
            "17394fd6-1018-4b26-877e-31b03e1d97db",
            {
                "id": "17394fd6-1018-4b26-877e-31b03e1d97db",
                "name": "UV",
                "type": "UV",
                "data": {
                    "position": {
                        "x": -556.875,
                        "y": 270.375
                    }
                },
                "inputs": {},
                "outputs": {
                    "aspectCorrected": {
                        "id": "8b41dade-d1bc-4673-874b-b24f33351a91",
                        "name": "Aspect Corrected",
                        "type": "vec2"
                    },
                    "uv": {
                        "id": "d91659e2-7c05-4997-9dbf-e0b9d62e2d20",
                        "name": "UV",
                        "type": "vec2"
                    },
                    "fragCoord": {
                        "id": "7b6a3eb5-eb34-42ec-9a23-90eb04fca837",
                        "name": "Frag Coord",
                        "type": "vec4"
                    }
                }
            }
        ],
        [
            "41e47893-dc50-441f-b657-c2ee326fbf87",
            {
                "id": "41e47893-dc50-441f-b657-c2ee326fbf87",
                "name": "Swizzle",
                "type": "SWIZZLE",
                "data": {
                    "position": {
                        "x": -266.5,
                        "y": 311.75
                    },
                    "type": {
                        "selected": "vec2",
                        "options": [
                            "vec2",
                            "vec3",
                            "vec4"
                        ]
                    }
                },
                "inputs": {
                    "vector": {
                        "id": "367c3cd3-291d-4738-bd75-c18f7033a90b",
                        "name": "Vector",
                        "type": "vec2",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "vec2",
                            "val": [
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                },
                                {
                                    "tag": "lit",
                                    "type": "float",
                                    "val": 0
                                }
                            ]
                        }
                    }
                },
                "outputs": {
                    "x": {
                        "id": "528b5162-993c-48e5-b4e9-7928e66bd40c",
                        "name": "X",
                        "type": "float"
                    },
                    "y": {
                        "id": "ae87ed86-f192-413b-8789-c9c585b411c9",
                        "name": "Y",
                        "type": "float"
                    }
                }
            }
        ],
        [
            "b84da403-ca3d-4870-a959-4f115c8c1b5e",
            {
                "id": "b84da403-ca3d-4870-a959-4f115c8c1b5e",
                "name": "Vector 4",
                "type": "VECTOR_4",
                "data": {
                    "position": {
                        "x": 35.5,
                        "y": 220.75
                    }
                },
                "inputs": {
                    "x": {
                        "id": "5896372f-e794-46f4-a291-90ceac5a47d9",
                        "name": "X",
                        "type": "float",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "float",
                            "val": 0
                        }
                    },
                    "y": {
                        "id": "5b9d42fe-a6c4-4b24-a1aa-b3735517a875",
                        "name": "Y",
                        "type": "float",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "float",
                            "val": 0
                        }
                    },
                    "z": {
                        "id": "068e80ed-14b6-4d95-963d-c21ff1e7c752",
                        "name": "Z",
                        "type": "float",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "float",
                            "val": 0
                        }
                    },
                    "w": {
                        "id": "53199eef-7046-4d1e-b344-6229b96e86cf",
                        "name": "W",
                        "type": "float",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "float",
                            "val": 1
                        },
                        "value": {
                            "tag": "lit",
                            "type": "float",
                            "val": 1
                        }
                    }
                },
                "outputs": {
                    "vector4": {
                        "id": "587fac1d-8b8f-4fb6-856c-5cb26c2eb9aa",
                        "name": "Vector 4",
                        "type": "vec4"
                    }
                }
            }
        ],
        [
            "be523300-a5bb-4887-b5d4-117b4aac4aa6",
            {
                "id": "be523300-a5bb-4887-b5d4-117b4aac4aa6",
                "name": "Time",
                "type": "TIME",
                "data": {
                    "position": {
                        "x": -621.25,
                        "y": 75.375
                    }
                },
                "inputs": {},
                "outputs": {
                    "time": {
                        "id": "912f8e39-973d-408c-96e8-0aa4feaa5d10",
                        "name": "Time",
                        "type": "float"
                    }
                }
            }
        ],
        [
            "da05fa64-73fe-4e8a-b24e-614e5c1319b0",
            {
                "id": "da05fa64-73fe-4e8a-b24e-614e5c1319b0",
                "name": "Sine",
                "type": "SINE",
                "data": {
                    "position": {
                        "x": -293.36376953125,
                        "y": 37.45458984375
                    },
                    "type": {
                        "selected": "float",
                        "options": [
                            "float",
                            "vec2",
                            "vec3",
                            "vec4"
                        ]
                    }
                },
                "inputs": {
                    "input": {
                        "id": "55203142-60ef-44f7-b536-1fbd882da361",
                        "name": "Input",
                        "type": "float",
                        "defaultValue": {
                            "tag": "lit",
                            "type": "float",
                            "val": 0
                        }
                    }
                },
                "outputs": {
                    "output": {
                        "id": "83e99f93-871f-49be-9d64-0e3e9e2a2b51",
                        "name": "Output",
                        "type": "float"
                    }
                }
            }
        ]
    ],
    "connections": [
        [
            "09352645-3ce4-4959-aa8a-ec0f2bb0fbaf",
            {
                "id": "09352645-3ce4-4959-aa8a-ec0f2bb0fbaf",
                "from": "d91659e2-7c05-4997-9dbf-e0b9d62e2d20",
                "to": "367c3cd3-291d-4738-bd75-c18f7033a90b"
            }
        ],
        [
            "23aa3199-e044-420d-849e-956724db0cc5",
            {
                "id": "23aa3199-e044-420d-849e-956724db0cc5",
                "from": "528b5162-993c-48e5-b4e9-7928e66bd40c",
                "to": "5896372f-e794-46f4-a291-90ceac5a47d9"
            }
        ],
        [
            "5f5b361d-2a32-482c-94ee-4b31e2a65ed4",
            {
                "id": "5f5b361d-2a32-482c-94ee-4b31e2a65ed4",
                "from": "ae87ed86-f192-413b-8789-c9c585b411c9",
                "to": "5b9d42fe-a6c4-4b24-a1aa-b3735517a875"
            }
        ],
        [
            "d5593a33-796d-41c5-97ff-0c63b4b4a707",
            {
                "id": "d5593a33-796d-41c5-97ff-0c63b4b4a707",
                "from": "587fac1d-8b8f-4fb6-856c-5cb26c2eb9aa",
                "to": "22370f15-7e0d-4529-9444-f6763afff4a5"
            }
        ],
        [
            "52046d4b-9ab7-448e-9a5f-f2b2c9885d32",
            {
                "id": "52046d4b-9ab7-448e-9a5f-f2b2c9885d32",
                "from": "912f8e39-973d-408c-96e8-0aa4feaa5d10",
                "to": "55203142-60ef-44f7-b536-1fbd882da361"
            }
        ],
        [
            "80579b46-e4f0-42c0-a7ba-103740d90111",
            {
                "id": "80579b46-e4f0-42c0-a7ba-103740d90111",
                "from": "83e99f93-871f-49be-9d64-0e3e9e2a2b51",
                "to": "068e80ed-14b6-4d95-963d-c21ff1e7c752"
            }
        ]
    ]
}
```

## Conclusion

Alma is a creative platform that encourages exploration and experimentation with generative graphics. Its intuitive interface enables artists, designers, and developers to easily bring their visions to life. 

This generative graphics tool has an extensive array of nodes, connections, and code nodes, offering endless possibilities for creating dynamic visual experiences. Since Alma is still in alpha stage, we can expect even more extensive and enhanced functionality to come!

---

## Get set up with LogRocket's modern error tracking in minutes:

1. Visit https://logrocket.com/signup/ to get an app ID.
2. Install LogRocket via NPM or script tag. `LogRocket.init()` must be called client-side, not server-side.

NPM:
```bash
$ npm i --save logrocket 

// Code:

import LogRocket from 'logrocket'; 
LogRocket.init('app/id');
```
Script Tag:
```javascript
Add to your HTML:

<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>
```

3.(Optional) Install plugins for deeper integrations with your stack:
*   Redux middleware
*   ngrx middleware
*   Vuex plugin

[Get started now](https://lp.logrocket.com/blg/signup)