VSGraph - A Visual Shader Graph Editor
Tags: shaders, glsl, webdev, javascript
Published: 2024-02-27 19:14:20

## What I've Been Building
Over the past couple months, I've been working on a tool for creating shaders, but without writing code. It uses HTML canvas to render all the nodes, a node tree for managing the execution, and dynamically builds GLSL on the fly based on the way the nodes are connected up visually. 

Here's a little preview of the canvas interface so you can get an idea of what I'm talking about. 

![vsgraph preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qob9h9g4a90g3kube5v1.png)



Over on the left hand side, we have the what's called the 'Graph'. This is where you will make new nodes and edit existing node connections. It supports using 'Shift + A' for showing the Add panel, and allows for zooming in an out wherever the mouse currently is with the scroll wheel for easier reading and dragging of node's edges.

On the right hand ride, we have the 'Viewer' this is where all output nodes, output their data to. Shader isn't the only output node available, there is also a color, number, and historical numerical graph output nodes. Each of them outputs their respective data types neatly into the viewer. 

Here's a little screenshot that shows you an example of using 3 different output types at once, to visual the data being produced by your graph.

![vsgraph preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2be4p9j065earm4ql1h.png)



I went through a ton of iterations on the style and exact way the nodes connected. Here's how the nodes used to look at the beginning.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ozh3ofeg7xmll0snnw2o.png)



These then progressed onto the below photo, adding colors to denote inputs and outputs. The colors at the point were still much to harsh to read, so I keep iterating.

![vsgraph preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/697dt54athkx1dvlhsjz.png)



Figured out that the input and output nodes would look much more readable with a lighter color, so I tried that too. Now we are getting something looking quite nice.

![vsgraph preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8kz9fd2do4rvzkmcpaj.png)




Now that the colors were decently readable as to not bother me, I moved on to implementing the Color output node. This one will take a vec3 node's output and display the color within the viewer for the user to inspect. 

![vsgraph preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05f1gbyvncisn61kb43y.png)




This was working quite well, so I starting adding a new type of nodes (Booleans). These were to be denoted with red node edge circles, and to go along with the theme, I made it so that all data type have their own distinct color on the node's edges so that the user doesn't have to guess which is which.

![vsgraph preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xr66v1yturj5sjw0mklj.png)




One of the last changes I made thus far, was changing the Input and Output node colors yet once again. I really liked the new colors. Made the whole thing 10x more readable with such a simple change.  

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/10n757vopoz338vk6r4j.png)




## How Does it Work?
In essence, each node is a simple JSON object, with some data describing it's name, inputs, outputs, an execute function that describe what operation takes place when the node should be executed (updated), and a glsl function that describes exactly what that node is translated to in GLSL. It uses a dynamically allocated id system for new nodes, so that **VSGraphs** can be saved and reloaded later in app, or exported directly into glsl for use in game engines or or shadershop.dev or any other platform that uses GLSL.

## What's Next?
Given what we have made so far, I am working on adding 50+ node types, and restructuring the way the nodes are added from the Add menu, so that it feels more similar to Blender, but modern. 

I would love to hear your thoughts on how you would use this tool, and what features you would like!

Please let me know in the comments!