Home

Awesome

Visual Studio Code - Shader Toy

<p align="center"> <a href="https://github.com/stevensona/shader-toy/actions"> <img src="https://github.com/stevensona/shader-toy/workflows/Build%20and%20Test/badge.svg"> </a> <a href="https://opensource.org/licenses/MIT" > <img src="https://img.shields.io/apm/l/vim-mode.svg"> </a> </p>

With this extension, view a live WebGL preview of GLSL shaders within VSCode, similar to shadertoy.com by providing a "Show GLSL Preview" command.

metaballs example

To run the command, either open the "Command Palette" and type "Shader Toy: Show GLSL Preview" or right-click inside a text editor and select "Shader Toy: Show GLSL Preview" from the context menu.

Running the command splits the view and displays a fullscreen quad with your shader applied. Your fragment shader's entry point is void main() or if that is unavailable void mainImage(out vec4, in vec2) where the first parameter is the output color and the second parameter is the fragments screen position.

An alternative command "Shader Toy: Show Static GLSL Preview" is available, which will open a preview that does not react to changing editors. An arbitrary amount of those views can be opened at one time, which enables a unique workflow to edit shaders that rely on multiple passes.

Features

Uniforms

At the moment, iResolution, iGlobalTime (also as iTime), iTimeDelta, iFrame, iMouse, iMouseButton, iDate, iSampleRate, iChannelN with N in [0, 9] and iChannelResolution[] are available uniforms.

Texture Input

The texture channels iChannelN may be defined by inserting code of the following form at the top of your shader

#iChannel0 "file://duck.png"
#iChannel1 "https://66.media.tumblr.com/tumblr_mcmeonhR1e1ridypxo1_500.jpg"
#iChannel2 "file://other/shader.glsl"
#iChannel2 "self"
#iChannel4 "file://music/epic.mp3"

This demonstrates using local and remote images as textures (Remember that power of 2 texture sizes is generally what you want to stick to.), using another shaders results as a texture, using the last frame of this shader by specifying self or using audio input. Note that to use relative paths for local input you will have to open a folder in Visual Code. texture example To influence the sampling behaviour of a texture, use the following syntax:

#iChannel0::MinFilter "NearestMipMapNearest"
#iChannel0::MagFilter "Nearest"
#iChannel0::WrapMode "Repeat"

Though keep in mind that, because of the WebGL standard, many options will only work with textures of width and height that are power of 2.

Cubemap Input

Cubemaps may be specified as any other texture, the fact that they are cubemaps is a combination of their path containing a wildcard and their type being explicitly stated.

#iChannel0 "file://cubemaps/yokohama_{}.jpg" // Note the wildcard '{}'
#iChannel0::Type "CubeMap"

The wildcard will be resolved by replacement with values from any of the following sets

If any of the six files can not be found, the next set is tried, starting from the first.

Audio Input (experimental)

Note: By default audio input is disabled, change the setting "Enable Audio Input" to use it.
Audio input is not supported from within Visual Studio Code, since ffmpeg is not shipped with Visual Studio Code, so you will have to generate a standalone version and host a local server to be able to load local files (or fiddle with your browsers security settings) if you want to use audio in your shaders. If your channel defines audio input, it will be inferred from the file extension. The channel will be a 2 pixels high and 512 pixels wide texture, where the width can be adjusted by the "Audio Domain Size" setting. The first row containing the audios frequency spectrum and the second row containing its waveform.

Keyboard Input

If you want to use keyboard input you can prepend #iKeyboard to your shader. This will expose to your shader the following functions:

bool isKeyPressed(int);
bool isKeyReleased(int);
bool isKeyDown(int);
bool isKeyToggled(int);

Additionally it will expose variables such as Key_A to Key_Z, Key_0 to Key_9, Key_UpArrow, Key_LeftArrow, Key_Shift, etc. Use these constants together with the functions mentioned above to query the state of a key.

Shader Includes

You may also include other files into your shader via a standard C-like syntax:

#include "some/shared/code.glsl"
#include "other/local/shader_code.glsl"
#include "d:/some/global/code.glsl"

These shaders may not define a void main() function and as such can be used only for utility functions, constant definitions etc.

Custom Uniforms (experimental and subject to change)

To use custom uniforms define those directly in your shader, giving an initial value as well as an optional range for the uniform.

#iUniform float my_scalar = 1.0 in { 0.0, 5.0 } // This will expose a slider to edit the value
#iUniform float my_discreet_scalar = 1.0 in { 0.0, 5.0 } step 0.2 // This will expose a slider incrementing at 0.2
#iUniform float other_scalar = 5.0 // This will expose a text field to give an arbitrary value
#iUniform color3 my_color = color3(1.0) // This will be editable as a color picker
#iUniform vec2 position_in_2d = vec2(1.0) // This will expose two text fields
#iUniform vec4 other_color = vec4(1.0) in { 0.0, 1.0 } // This will expose four sliders

 `iViewMatrix`, a mat4 with the view matrix. Must use directive `#iFirstPersonControls` in order to control, otherwise it remains identity.
 Controls:
 <b>WASD</b> move, <b>R|F</b> up | down, <b>Q|E</b> roll, <b>up|down</b> pitch, <b>left|right</b> yaw

Compatibility with Shadertoy.com

The following is an example of a shader ported from shadertoy.com:

// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// Created by S.Guillitte
void main() {
  float time = iGlobalTime * 1.0;
  vec2 uv = (gl_FragCoord.xy / iResolution.xx - 0.5) * 8.0;
  vec2 uv0 = uv;
  float i0 = 1.0;
  float i1 = 1.0;
  float i2 = 1.0;
  float i4 = 0.0;
  for (int s = 0; s < 7; s++) {
    vec2 r;
    r = vec2(cos(uv.y * i0 - i4 + time / i1), sin(uv.x * i0 - i4 + time / i1)) / i2;
    r += vec2(-r.y, r.x) * 0.3;
    uv.xy += r;

    i0 *= 1.93;
    i1 *= 1.15;
    i2 *= 1.7;
    i4 += 0.05 + 0.1 * time * i1;
  }
  float r = sin(uv.x - time) * 0.5 + 0.5;
  float b = sin(uv.y + time) * 0.5 + 0.5;
  float g = sin((uv.x + uv.y + sin(time * 0.5)) * 0.5) * 0.5 + 0.5;
  gl_FragColor = vec4(r, g, b, 1.0);
}

Note that compared to shadertoy.com gl_FragCoord replaces fragCoord and gl_FragColor replaces fragColor in the original demo. There is however a rudimentary support for inserting a trivial void main() which will delegate to a void mainImage(out vec4, in vec2) function. The definition of void main() is found by matching the regex /void\s+main\s*\(\s*\)\s*\{/g, thus if you require to define void main() in addition to the extension generating a definition you may define it as void main(void). This might be necessary, for example, if your main definition would be processed away by the preprocessor and should thus not be picked up by the extension. Since compatibility is achieved with a simple regex match it is only semi-reliable. If you only use shaders from shadertoy.com that do things such as defining mainImage via macros you may want to enable the "Shader Toy Strict Compatibility" setting, which disables the ability to use shaders that define void main() and only allows shaders that define mainImage in some way. Alternatively you can use #StrictCompatibility in your shader to have this feature localized to just that shader.

Integration of glslify

You can enable support for glslify in the settings, but because glslify does not support line mappings pre and post its transform, line numbers on errors will unfortunately be disabled as long as you have the setting enabled. Using glslify allows using a node.js-style module system for your shaders:

#pragma glslify: snoise = require('glsl-noise/simplex/2d')

float noise(in vec2 pt) {
    return snoise(pt) * 0.5 + 0.5;
}

void main () {
    float r = noise(gl_FragCoord.xy * 0.01);
    float g = noise(gl_FragCoord.xy * 0.01 + 100.0);
    float b = noise(gl_FragCoord.xy * 0.01 + 300.0);
    gl_FragColor = vec4(r, g, b, 1);
}

GLSL Preview Interaction

The extension provides a pause button inside the GLSL Preview to stop the progression of time. In conjunction with this you can use the screenshot button provided inside the GLSL Preview to capture and save a frame. The resolution of the saved screenshot will by default be the same resolution as the GLSL Preview, though a setting is available that allows the user to override the resolution with an arbitrary value. A recording button is also available, the quality as well as the size of the recording is determined by the webview. Lastly the extension provides a superficial view into the shaders performance and memory consumption.

Error Highlighting

The extension also supports highlighting of compilation errors in the text editor, for single shaders but also for multiple passes. It does so by showing errors as diagnostics directly in the text editor as well as presenting them in a digestible format inside the GLSL Preview and allowing the user to interact with the error messages to jump to the relevant lines, and open the relevant files if necessary:

error example

Recording Capabilities

Two rendering modes are supported:

The default is real-time rendering to activate offline rendering set shader-toy.recordOfflineto true.

Shared parameters

Real-time Rendering parameters

Offline rendering parameters

Requirements

Known Issues

Contributing

Contributions of any kind are welcome and encouraged.

GitHub Project Page

Contributing Guidelines

Visual Studio Marketplace

Release Notes

0.11.3

0.11.2

0.11.1

0.11.0

0.10.15

0.10.14

0.10.13

0.10.11

0.10.10

0.10.9

0.10.8

0.10.7

0.10.6

0.10.5

0.10.4

0.10.3

0.10.2

0.10.1

0.9.2

0.9.1

0.9.0

0.8.10

0.8.9

0.8.8

0.8.7

0.8.6

0.8.5

0.8.4

0.8.3

0.8.2

0.8.0

0.7.10

0.7.9

0.7.6

0.7.5

0.7.4

0.7.3

0.7.2

0.7.1

0.7.0

0.1.6

This patch adds the ability to view GLSL compiler errors. They are currently displayed as a list in the preview viewport.

0.1.5

Fix for error when settings.json is not present (no textures defined)

0.1.4

Adds support for texture channels.

0.1.3

Add support for a few more of the uniforms, and implements a 1 second time delay between modifying the source and recompilation.

0.1.1

Initial release of shadertoy for vscode. Many uniforms not available.

Acknowledgements

Screenshot feature's camera icon made by Smashicons from www.flaticon.com.