Giter Club home page Giter Club logo

shader-toy's Introduction

Visual Studio Code - Shader Toy

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

  • [ 'e', 'w', 'u', 'd', 'n', 's' ],
  • [ 'east', 'west', 'up', 'down', 'north', 'south' ],
  • [ 'px', 'nx', 'py', 'ny', 'pz', 'nz' ] or
  • [ 'posx', 'negx', 'posy', 'negy', 'posz', 'negz' ].

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

Requirements

  • A graphics card supporting WebGL.

Known Issues

  • Performance at the moment is not great for certain shaders, and the cause is under investigation
  • Shaders with audio from remote sources are currently not working properly, this is however an issue on VSCode side and will be fixed when releasing with Electron 6.
  • There seems to be a very rare bug that causes audio inputs to sound corrupted.

Contributing

Contributions of any kind are welcome and encouraged.

GitHub Project Page

Contributing Guidelines

Visual Studio Marketplace

Release Notes

0.11.3

  • Added option to reload on save,
  • fixed a bug where glslify would never find modules.

0.11.2

  • Added free fly controls,
  • fixed a bug that would result in recording the frame time panel.

0.11.1

  • Added option to maintain pause state when reloading the shader,
  • added ability to record the shader,
  • fixed first frame of mouse down mismatch with online version,
  • added setting to not compile included files separately.

0.11.0

  • Use the async interface for file I/O.

0.10.15

  • Lex numbers with exponents as floating point, not integer,
  • make assignability testing more robust.

0.10.14

  • Hotfix, extension was trying to run a non-existant file.

0.10.13

  • Fix attributions of several demo shaders,
  • align default wrap mode with what is default on shadertoy.com,
  • allow control of filter and wrap mode for sampling other shaders,
  • add a strict compatibility mode for shadertoy.com,
  • add setting to skip all automatic recompilation and instead have a button in the webview for that.

0.10.11

  • Automatic dependency updates.

0.10.10

  • Fix stats display,
  • fix includes and shader names resolving on only their filename,
  • fix shader reloading on extension settings changing.

0.10.9

  • Hotfix a freeze when parsing some multiline c-style comments.

0.10.8

  • Hotfix to make the extension work with the web version of VSCode.

0.10.7

  • Make all uniform vector types use separate UI for editing them at runtime,
  • add a color3 uniform type when the user explicitly wants a color edit field,
  • fix an error where using uniforms could cause the extension to become unresponsive when mixing unexpected types,
  • introduce the step keyword to allow setting an increment for uniform values,
  • improve error reporting for parsing errors when files are included early in a shader.

0.10.6

  • Add commands corresponding to UI buttons to allow custom keybindings. Thank you @Ayassaka

0.10.5

  • Fix bug that caused the static preview command to open a dynamic preview,
  • fix a bug when parsing back-to-back comments
  • fix a bug with uniforms that have more than one and not exactly three components,
  • fully support floating point parsing, including exponents.

0.10.4

  • Fix an issue that caused a full webview recreation on a recompile,
  • made webview not grab focus when it is being created.

0.10.3

  • Improve error diagnostic for texture settings,
  • add a command to generate a portable file of the GLSL preview,
  • fix a bug a bug where MinFilter was not recognised as a valid setting,
  • add basic support for cubemaps,
  • fix an issue that would not allow arbitrary local resources from absolute paths.

0.10.2

  • Hotfix for infinite loop while parsing a shader.

0.10.1

  • Correctly parse comments in GLSL code, allowing to remove e.g. texture definitions with both single- as well as multi-line comments,
  • changed syntax for uniform definitions to align closer to standard GLSL syntax,
  • allow definitions of e.g. textures to be made in include files,
  • reworked path resolution for files, adding the possibility to find files relative to the file they are used in,
  • make the initial './' in relative paths optional,
  • reload shaders when their dependents change, e.g. when included files change,
  • maintain state of uniforms gui across reloads.

0.9.2

  • Add controls for custom uniforms,
  • add documentation for custom uniforms,
  • add a static GLSL view for working on multi pass projects,
  • enabled code to be loaded from visible editors instead of files.

0.9.1

  • Small refactor to improve development iteration time,
  • add support for multiple folders in a workspace,
  • add support for custom screenshot resolution,
  • fix a type mismatch for forceAspectRatio setting,
  • added experimental, undocumented support for custom uniforms.

0.9.0

  • Major refactoring,
  • added support for iChannelResolution.

0.8.10

  • Fix bugs that allowed only one shader to be parsed.

0.8.9

  • Added rudimentary support for glslify,
  • added support for texture sampling and wrapping options,
  • fix includes to allow going into depth rather than only one level deep.

0.8.8

  • Update iFrame after a frame is rendered instead of before, so that the first frames value is zero,
  • fixed a bug that caused deprecation warnings to be shown only if the user meant to disable them,
  • fixed a bug with wrong line numbers being displayed if the shader contains a version directive,
  • enabled diagnostics correctly when using multiple passes,
  • allow specifying a path for a shader as input even if the path refers to the very same shader, thus removing the need for the self keyword despite being a shorthand,
  • added shader compile-time panel to stats,
  • fixed bug that caused circular dependencies between passes not to work.

0.8.7

  • Hotfix for typo.

0.8.6

  • Document how main definition is found,
  • remove version directives from shaders,
  • fix an issue that would remove all newlines from beginning of shader and cause errors to be reported on the wrong lines,
  • reintroduce error when textures could not be loaded,
  • add iGlobalFrame,
  • add option that shows compile errors as diagnostics, enabled by default.

0.8.5

  • Hotfix for missing dependencies.

0.8.4

  • The extension now reloads the GLSL Preview when the user changes the extension's settings,
  • iTime, iMouse and iKeyboard states now persist across compilations of the same shader,
  • added an option to persist state also when changing the shader that is previewed, disabled by default,
  • fixed bug that caused a reload of the preview when unfocusing and refocusing the previewed editor,
  • added icon to GLSL Preview,
  • deprecated input definitions inside settings.json in favour of inside the shader,
  • fixed a bug that broke line highlighting from GLSL compile errors,
  • added experimental ability use audio as input to shaders,
  • added iSampleRate uniform, which holds the sample rate of the audio context,
  • deprecated input definitions using different "protocols", instead the type of input is inferred from the extension,
  • deprecated requirement of using a "protocol" for includes,
  • added iDate uniform, which holds year, month, day and seconds in day in its components,
  • fixed a bug that caused shaders defining void mainImage(out vec4, in vec2) without in qualifier to not compile,
  • added ability to specify input in quotes, rather than freestanding, which removes some bugs with spaces in file paths,
  • deprecated omitting quotes when specifying input,
  • added option to omit deprecation warnings, disabled by default,
  • introduced a small update message.

0.8.3

  • Hotfix for texture loading bug introduced in the last version.

0.8.2

  • Fixed issue with path generation on Linux and MacOS resulting in a broken experience,
  • fixed issue where editor changes would trigger a shader reload even if they were not text editors.

0.8.0

  • Refactored a lot of code to use Visual Studio Code's WebView API instead of its deprecated PreviewHtml command.

0.7.10

  • Fixed behaviour of iMouse to resemble shaderoty.com as close as possible,
  • added iMouseButton uniform which holds left mousebutton in x and right mousebutton in y, 0 being up and 1 being down.

0.7.9

  • Added setting to enforce aspect ratio, this has to be entered manually into users settings.json,
  • added setting to enable a screenshot button to save the current frame as a png, enabled by default.

0.7.6

  • Added experimental support for keyboard input.

0.7.5

  • Added experimental support for includes, relative to the shader file.

0.7.4

  • Added support for using the current shader as input, thus allowing it to feed into itself (experimental),
  • improved error handling in some cases,
  • fixed a bug that would cause a iChannel definition inside a shader to be parsed even when commented out,
  • added an option that allows users to specify the delay between shader edits and shader reloads,
  • added an option to emit a warning when a shader uses an iChannel that is not defined (experimental),
  • added an option which gives the user a pause button inside the GLSL preview.

0.7.3

  • Added support for WebGL 2.0 if available,
  • using higher precision textures if available.

0.7.2

  • Hotfix for a bug which would cause users to crash on any shader preview.

0.7.1

  • Added support for using other shaders as inputs (experimental),
  • promoted definition of textures in shader from experimental to full feature,
  • now allows for using paths relative to the working directory,
  • improved support for compiler errors, which can now be used to highlight the erroneous lines,
  • improved compatibility with original shader-toy shaders by allowing shaders missing void main but providing void mainImage,
  • added shader preview command to context menu.

0.7.0

  • Fixes the issue with wrongly corresponding line numbers on compiler errors,
  • adds a preprocessor definition SHADER_TOY to disambiguate easier where your shader is running,
  • allows specifying textures inside the shader instead of inside the vs-vode options (experimental),
  • adds an option which uses a remote stats.js to show frame time,
  • added support for the iFrame uniform,
  • added support for the iMouse uniform,'
  • added option to reload shaders when changing the editor.

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.

shader-toy's People

Contributors

dependabot[bot] avatar gam0022 avatar gurten avatar jz-wenxuan avatar klab-hosoda-sho avatar malacath-92 avatar mjbvz avatar pflannery avatar stef-levesque avatar stevensona avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shader-toy's Issues

No content in preview window

When running the preview command, the preview window opens, but no content is visible. The developer console shows the generated page, and the error: [Embedded Page] Uncaught ReferenceError: THREE is not defined

From my quick review of the generated code, it looks like the canvas and all relevant script tags are generated after the </body> tag, which seems problematic.

The full generated code (edited for privacy):

<head>
  <style>
      html, body, #canvas { margin: 0; padding: 0; width: 100%; height: 100%; display: block; }
      #error {font-family: Consolas; font-size: 1.2em; color:#ccc; background-color:black; font-weight: bold;}
  </style>
</head>
<body>
      <div id="error"></div>
      <div id="container"></div>
</body>
<script src="/home/user/.vscode/extensions/stevensona.shader-toy-0.1.8/resources/jquery.min.js"></script>
<script src="/home/user/.vscode/extensions/stevensona.shader-toy-0.1.8/resources/three.min.js"></script>
<canvas id="canvas"></canvas>
<script id="vs" type="x-shader/x-vertex">
    void main() {
        gl_Position = vec4(position, 1.0);
    }
</script>
<script id="fs" type="x-shader/x-fragment">
    uniform vec3        iResolution;
    uniform float       iGlobalTime;
    uniform float       iTimeDelta;
    uniform int         iFrame;
    uniform float       iChannelTime[4];
    uniform vec3        iChannelResolution[4];
    uniform vec4        iMouse;
    uniform sampler2D   iChannel0;
    uniform sampler2D   iChannel1;
    uniform sampler2D   iChannel2;
    uniform sampler2D   iChannel3;
//                  uniform vec4        iDate;
//                  uniform float       iSampleRate;
    
    void main()
{
// -- snip --
}
</script>

<script type="text/javascript">
    (function(){
        console.error = function (message) {
            if('7' in arguments) {
                $("#error").html("<h3>Shader failed to compile</h3><ul>")                                    
                $("#error").append(arguments[7].replace(/ERROR: \d+:(\d+)/g, function(m, c) { return  "<li>Line " + String(Number(c) - 27); }));
                $("#error").append("</ul>");
            }
        };
    })();
    var canvas = document.getElementById('canvas');
    var scene = new THREE.Scene();
    var renderer = new THREE.WebGLRenderer({canvas: canvas, antialias: true});
    var camera = new THREE.PerspectiveCamera(45, canvas.clientWidth / canvas.clientWidth, 1, 1000);
    var clock = new THREE.Clock();
    var resolution = new THREE.Vector3(canvas.clientWidth, canvas.clientHeight, 1.0);
    var channelResolution = new THREE.Vector3(128.0, 128.0, 0.0);
    var mouse = new THREE.Vector4(0, 0, 0, 0);
    var shader = new THREE.ShaderMaterial({
            vertexShader: document.getElementById('vs').textContent,
            fragmentShader: document.getElementById('fs').textContent,
            depthWrite: false,
            depthTest: false,
            uniforms: {
                iResolution: { type: "v3", value: resolution },
                iGlobalTime: { type: "f", value: 0.0 },
                iTimeDelta: { type: "f", value: 0.0 },
                iFrame: { type: "i", value: 0 },
                iChannelTime: { type: "fv1", value: [0., 0., 0., 0.] },
                iChannelResolution: { type: "v3v", value:
                    [channelResolution, channelResolution, channelResolution, channelResolution]   
                },
                iMouse: { type: "v4", value: mouse },
            }
        });
    if(false) {
        Function.prototype;
        Function.prototype;
        Function.prototype;
        Function.prototype;
    }
    var quad = new THREE.Mesh(
        new THREE.PlaneGeometry(2, 2),
        shader
    );
    scene.add(quad);
    camera.position.z = 10;

    render();

    function render() {
        requestAnimationFrame(render);
        if (canvas.width !== canvas.clientWidth || canvas.height !== canvas.clientHeight) {
            renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
            camera.aspect = canvas.clientWidth /  canvas.clientHeight;
            camera.updateProjectionMatrix();
            resolution = new THREE.Vector3(canvas.clientWidth, canvas.clientHeight, 1.0);
        }
        
        
        shader.uniforms['iResolution'].value = resolution;
        shader.uniforms['iGlobalTime'].value = clock.getElapsedTime();
        shader.uniforms['iTimeDelta'].value = clock.getDelta();
        shader.uniforms['iFrame'].value = 0;
        shader.uniforms['iMouse'].value = mouse;

        renderer.render(scene, camera);
    }
</script>

Can shader-toy support relative local require for glslify?

#pragma glslify: value_noise21 = require("..\Include\value_noise21.glsl") // not working...
#pragma glslify: simplex_noise21 = require("F:\git\shadertoy\Include\value_noise21.glsl") //works... 

I think local glslify module is useful to develop daily, thus it'll be very convinent if shadertoy support it. thanks!

improve ShaderToy mode detection

I'm using the following boilerplate code to make shaders compatible with ShaderToy and standard compilers (that includes VSCode extensions like Shaderc GLSL Linter):

//#version 460
precision highp float;

#ifdef STDGLSL
layout(location = 0) in VertexData
{
	vec4 v_position;
	vec3 v_normal;
	vec2 v_texcoord;
};
layout(location = 0) out vec4 fragColor;
layout(binding = 0) uniform ShadertoyBlock
{
	vec3 iResolution;
	float iGlobalTime;
	float iTimeDelta;
	int iFrame;
	vec4 iMouse;
	vec4 iDate;
	float iSampleRate;
};
float iTime = iGlobalTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;
uniform sampler2D iChannel3;

void mainImage(out vec4, in vec2);
void main(void) { mainImage(fragColor, v_texcoord * iResolution.xy); }
#else
#iChannel0 "file://./text.png"
#endif

This works quite nicely but there are 2 issues:

  • Had to change main() to main(void), otherwise your regex would pick it up and not generate its own main. Should be documented or improved (better preprocessor handling).
  • I can't use the version directive obviously (can't ifdef it). It only works because the shaderc extension offers an option for defining it via the commandline. Any ideas?

support for texture arrays, MRT, integer textures, image load/store?

hi, i just came across your project - nice!
i'm currently working on something similar to help me with my lightmapping / path tracing research. i'd be interested in collaborating. here's the list of features beyond what ShaderToy supports that i'm currently supporting:

texture arrays
volume textures
multiple rendertargets
up to 32 texture inputs per pass
arbitrary texture resolutions
all GPU-supported texture formats
image load/store (and atomics)
arbitrary number of passes
slider widgets defined in metadata and rendered as an overlay
all declarations in metadata in the shader code .. e.g. to create a 1024x1024 buffer you just write "//$BUFFER:mybuffer,w=1024,h=1024" in the shader code, and then you can sample it with "texture(mybuffer,...)" etc.

send me an email if you are interested in sharing ideas or unifying our syntax!
[email protected]

Make compatible OpenGL glsls version 330 ?

I don't know if it is possible to make this awesome plugin compatible with (Desktop) OpenGL.
I am creating shaders for desktop GLSL and they don't seem to display without modifications.

mouse input

Could mouse input in the preview be available?

Very high CPU usage compared to Shadertoy

On my desktop this is not really a problem but on my laptop with an integrated GPU, the CPU usage goes up to 50%+ on all threads compared to ~15% on the regular Shadertoy website using the same very basic shader code.

I don't know if this is because of a limitation by VSCode or something?

Type mismatch on forceAspectRatio

I'm trying to force the aspect ratio to be 16:9 (with "shader-toy.forceAspectRatio": [16, 9]), but I get the warning

Incorrect type. Expected one of number, number.

Edit: Shader still works fine, this is a very minor issue

Nothing happends

Hi

I have the extension installed, I added a test shader, opened the extension, and the preview stays blank and no error is shown in the console.

screen shot 2017-02-21 at 11 21 39

Version 0.8.4 on Mac 10.14.4 doesn't work.

After upgrade to 0.8.4 my Shadertoy Preview doesn't work and always prompt me "Can't found shader-toy command" even I reinstall the extension and reinstall VSCode. When I downgrade to 0.8.3 extension works fine.

My OS is Mac 10.14.4 and VSCode version is 1.34.0
image
How can I fix this?

Compile errors

Hi there :)

Well showing compile errors would be great. Or at least highlighting the line which has a problem.

"To use relative paths please open a workspace"

I have already saved a new workspace with the glsl file open and saved it, then reopened the workspace - still get this error followed by; 'Unable to open 'GLSL Preview": ENOENT: no such file or directory ...\undefined\other-shader.glsl

missing variable "iGlobalTime" recently

As of the last few weeks , June 2019, I noticed none of my shaders work. They all complain that the variable "iGlobalTime" is not defined.
I am using the 64 bit version on Windows 10.
Any help would be most welcomed
Thanks,
sj

Relative path resolution when including files

Hello,

I have encountered an issue with path resolution. The problem is as follows

I have my main.glsl fragment shader in the root folder and all my dependancies in deps folder

project/
   ├ deps/
   |   ├ dep1.glsl
   |   └ dep2.glsl
   └ main.glsl

my main.glsl has a line

#include "./deps/dep1.glsl"

and my dep1.glsl has a line

#include "./dep2.glsl"

and I get an error that dep2.glsl cannot be found, but when I prepend "./deps" to the path so the line in dep1.glsl looks like

#include "./deps/dep2.glsl"

everything works fine.

It's a minor issue but gets in the way of having some shared resources in multiple projects without copying them each time (as the paths will be different)

Audio input not work with Visual Code 1.35.1

I had update my Visual Code to 1.35.1, and update the Shader Toy plugin to 0.8.8,
and then I open the audio input setting, put the mp3 to the right place(if path is not correct, it will notice what went wrong),but when i preview with the shader, the audio input channel still not work, and has none error or notice. From the issue i know it added from 0.8.4, so if i want to experience, What shall I do?

Off-Topic for Adam Stevenson

Hi Adam
This is not a SPAM message.

My name is Nick Gorbikoff - I'm an it director over at AJR International, a company in Glendale Heights, IL . We got your resume through indeed.com and tried to contact you, but I'm guessing it went to SPAM.
If you are still interested in a Ruby Developer position, please reach out to me

Kind Regards,

Nick Gorbikoff
IT Director

AJR International
300 Regency Drive
Glendale Heights, IL 60139

t: (630) 832-0222 x 242
f: (630) 832-0333
e: [email protected]
w: www.ajrintl.com

bug: shader doesn't get rendered and doesn't display any error

Hello

My shader get not rendered. The Fps counter is running and no error gets displayed, but only the VS background color is rendered.

I'm developing a shader for a Phone background. This shader is programmed to run on the "shader editor" app: appstore. The shader runs without any problems on this app.(undefine "on_vs" for use on the app.)

My guess for the cause of this problem: I use arrays in my shader.

my shader:

#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif

#define on_vs
#ifdef on_vs
  vec2 resolution = iResolution.xy;
  float time = iGlobalTime;
  vec2 offset = iMouse.xy / iResolution.xy * vec2(-1.0, -1.0);
#else
  uniform vec2 resolution;
  uniform float time;
  uniform vec2 offset;
#endif

void cswap(inout vec3[8] points, inout float[8] pdistance, int i){
  if(pdistance[i]>pdistance[i+1]){
    float tempf = pdistance[i];
    pdistance[i] = pdistance[i+1];
    pdistance[i+1] = tempf;

    vec3 tempv3 = points[i];
    points[i] =  points[i+1];
    points[i+1] = tempv3;
  }
}
void sort(inout vec3[8] points, inout float[8] pdistance){
  
  cswap(points,pdistance,0);
  cswap(points,pdistance,2);
  cswap(points,pdistance,4);
  cswap(points,pdistance,6);

  cswap(points,pdistance,1);
  cswap(points,pdistance,3);
  cswap(points,pdistance,5);

  cswap(points,pdistance,2);
  cswap(points,pdistance,4);

  cswap(points,pdistance,3);

  cswap(points,pdistance,2);
  cswap(points,pdistance,4);

  cswap(points,pdistance,1);
  cswap(points,pdistance,3);
  cswap(points,pdistance,5);

  cswap(points,pdistance,0);
  cswap(points,pdistance,2);
  cswap(points,pdistance,4);
  cswap(points,pdistance,6);
}

void FAST32_hash_3D(   vec3 gridcell,
            out vec4 lowz_hash_0,
            out vec4 lowz_hash_1,
            out vec4 lowz_hash_2,
            out vec4 highz_hash_0,
            out vec4 highz_hash_1,
            out vec4 highz_hash_2  )    //  generates 3 random numbers for each of the 8 cell corners
{
  //    gridcell is assumed to be an integer coordinate
  //  TODO:   these constants need tweaked to find the best possible noise.
  //      probably requires some kind of brute force computational searching or something....
  const vec2 OFFSET = vec2( 50.0, 161.0 );
  const float DOMAIN = 69.0;
  const vec3 SOMELARGEFLOATS = vec3( 635.298681, 682.357502, 668.926525 );
  const vec3 ZINC = vec3( 48.500388, 65.294118, 63.934599 );
  //  truncate the domain
  gridcell.xyz = gridcell.xyz - floor(gridcell.xyz * ( 1.0 / DOMAIN )) * DOMAIN;
  vec3 gridcell_inc1 = step( gridcell, vec3( DOMAIN - 1.5, DOMAIN - 1.5, DOMAIN - 1.5 ) ) * ( gridcell + 1.0 );
  //  calculate the noise
  vec4 P = vec4( gridcell.xy, gridcell_inc1.xy ) + OFFSET.xyxy;
  P *= P;
  P = P.xzxz * P.yyww;
  vec3 lowz_mod = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + gridcell.zzz * ZINC.xyz ) );
  vec3 highz_mod = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + gridcell_inc1.zzz * ZINC.xyz ) );
  lowz_hash_0 = fract( P * lowz_mod.xxxx );
  highz_hash_0 = fract( P * highz_mod.xxxx );
  lowz_hash_1 = fract( P * lowz_mod.yyyy );
  highz_hash_1 = fract( P * highz_mod.yyyy );
  lowz_hash_2 = fract( P * lowz_mod.zzzz );
  highz_hash_2 = fract( P * highz_mod.zzzz );
}
//  convert a 0.0->1.0 sample to a -1.0->1.0 sample weighted towards the extremes
vec4 Cellular_weight_samples( vec4 samples )
{
  samples = samples * 2.0 - 1.0;
  //return (1.0 - samples * samples) * sign(samples);  // square
  return (samples * samples * samples) - sign(samples);  // cubic (even more variance)
}
//
//  Cellular Noise 3D
//  Based off Stefan Gustavson's work at http://www.itn.liu.se/~stegu/GLSL-cellular
//  http://briansharpe.files.wordpress.com/2011/12/cellularsample.jpg
//
//  Speed up by using 2x2x2 search window instead of 3x3x3
//  produces range of 0.0->1.0
//
float Cellular3D(vec3 P)
{
  //  establish our grid cell and unit position
  vec3 Pi = floor(P);
  vec3 Pf = P - Pi;
  //  calculate the hash.
  //  ( various hashing methods listed in order of speed )
  vec4 hash_x0, hash_y0, hash_z0, hash_x1, hash_y1, hash_z1;
  FAST32_hash_3D( Pi, hash_x0, hash_y0, hash_z0, hash_x1, hash_y1, hash_z1 );
  //  generate the 8 random points
  //  restrict the random point offset to eliminate artifacts
  //  we'll improve the variance of the noise by pushing the points to the extremes of the jitter window
  const float JITTER_WINDOW = 0.23;  // 0.166666666 will guarentee no artifacts. It is the intersection on x of graphs f(x)=( (0.5 + (0.5-x))^2 + 2*((0.5-x)^2) ) and f(x)=( 2 * (( 0.5 + x )^2) + x * x )
  hash_x0 = Cellular_weight_samples( hash_x0 ) * JITTER_WINDOW + vec4(0.0, 1.0, 0.0, 1.0);
  hash_y0 = Cellular_weight_samples( hash_y0 ) * JITTER_WINDOW + vec4(0.0, 0.0, 1.0, 1.0);
  hash_x1 = Cellular_weight_samples( hash_x1 ) * JITTER_WINDOW + vec4(0.0, 1.0, 0.0, 1.0);
  hash_y1 = Cellular_weight_samples( hash_y1 ) * JITTER_WINDOW + vec4(0.0, 0.0, 1.0, 1.0);
  hash_z0 = Cellular_weight_samples( hash_z0 ) * JITTER_WINDOW + vec4(0.0, 0.0, 0.0, 0.0);
  hash_z1 = Cellular_weight_samples( hash_z1 ) * JITTER_WINDOW + vec4(1.0, 1.0, 1.0, 1.0);
  //  return the closest squared distance
  vec4 dx1 = Pf.xxxx - hash_x0;
  vec4 dy1 = Pf.yyyy - hash_y0;
  vec4 dz1 = Pf.zzzz - hash_z0;
  vec4 dx2 = Pf.xxxx - hash_x1;
  vec4 dy2 = Pf.yyyy - hash_y1;
  vec4 dz2 = Pf.zzzz - hash_z1;
  vec4 d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1;
  vec4 d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2;
  
  vec3 points[8];
  points[0] = vec3(dx1.x,dy1.x,dz1.x);
  points[1] = vec3(dx1.y,dy1.y,dz1.y);
  points[2] = vec3(dx1.z,dy1.z,dz1.z);
  points[3] = vec3(dx1.w,dy1.w,dz1.w);
  points[4] = vec3(dx2.x,dy2.x,dz2.x);
  points[5] = vec3(dx2.y,dy2.y,dz2.y);
  points[6] = vec3(dx2.z,dy2.z,dz2.z);
  points[7] = vec3(dx2.w,dy2.w,dz2.w);
  
  float pdistance[8];
  pdistance[0] = d1.x;
  pdistance[1] = d1.y;
  pdistance[2] = d1.z;
  pdistance[3] = d1.w;
  pdistance[4] = d2.x;
  pdistance[5] = d2.y;
  pdistance[6] = d2.z;
  pdistance[7] = d2.w;

  sort(points, pdistance);

  vec3 minv = vec3(pdistance[0],pdistance[1],pdistance[2]);

  float delta = (abs(minv.x - minv.y) + abs(minv.x - minv.z) + abs(minv.y - minv.z))/3.0;
  float temp = ((minv.y / minv.x)/3.0) * -1.0 + 1.0;
  float distance_to_middle = (minv.x + minv.y) / 2.0;
  float c_to_mid = (distance_to_middle - minv.x);
  c_to_mid /= distance_to_middle;
  c_to_mid = c_to_mid * -1.0 + 1.0;
  return smoothstep(0.93,1.0,c_to_mid);
  return minv.x;
}
float CellFast(vec3 p, vec3 offset, float frequency, float amplitude)
{
  float h = Cellular3D((p + offset) * frequency);
  h *= amplitude;
  return h;
}

vec2 rotate(vec2 pos, float angle){
  float a = atan(pos.x/pos.y);
  float l = sqrt(pos.x * pos.x + pos.y * pos.y);
  a += angle;
  pos.x = l*cos(a);
  pos.y = l*sin(a);
  return pos;
}

void main(void) {
  float max_res = max(resolution.x,resolution.y);
  vec2 uv = gl_FragCoord.xy /max_res;
  vec2 soffset = offset * 0.7;

  vec3 pos = vec3(uv + soffset,time/200.0);
  pos.yz = rotate(pos.yz, 0.1);

  float heigth = CellFast(pos, vec3(1.0,1.0,1.0), 8.0, 1.0);
  
  gl_FragColor = vec4(heigth, heigth, heigth, 1.0);
}

Audio channels

Similar to Shadertoy.com, support audio channels as inputs into shaders.

Suggested by @edap

iChannelResolution support

Shadertoy.com use pre-defined uniform:
uniform vec3 iChannelResolution[4]
for texture image size ino. Using them in shader-toy seems not work.

Error messages show wrong line number

The line number mentioned in the error is not the same line where the error actually is.

Example:

#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265359

void main() {
    vec2 st = gl_FragCoord.xy/iResolution.xy;
    vec2 origin = vec2(0.5, 0.5);
    vec2 d = distance(st, origin);

    float r = d;

    float g = r;
    float b = r;

    vec3 color = vec3(r, g, b);

    gl_FragColor = vec4(color,1.0);
}

Error:

Shader failed to compile

Line 97: '=' : dimension mismatch
Line 97: '=' : cannot convert from 'mediump float' to 'mediump 2-component vector of float'
Line 99: '=' : dimension mismatch
Line 99: '=' : cannot convert from 'mediump 2-component vector of float' to 'mediump float'

image

Feature Request: Resolution Setting

It would be great to have an option to set resolution/size for the preview window. It's a minor thing and I have a workaround by putting a small window underneath.

Can't LOAD the TEXTURE!

my glsl code is :

void main()
{
gl_FragColor = texture2D(iChannel0, gl_FragCoord.xy);
}

and my folder is:
.vscode
test.glsl
normalmap_2.png

my settings.json is:

{
"shader-toy.textures": {
"0": "./normalmap_2.png"
}
}

BUT, I can't see the image anywhere! and the image is power of two...
please help me...

Restart of VS Code is required to reset the preview with the current shader file.

Restart of VS Code is required to reset the preview with the current shader file.
If I open the shader preview with a working shader (no errors), it's not possible to open another glsl-file for the preview. The preview still shows the first shader.

Reproduce:

  1. Open a glsl-file.
  2. Show preview tab.
  3. Change the file / Switch to another file.

Result: The preview does not switch to the selected file. Also after closing the tab and reopen with command. It does only work if I restart VS Code.
Summary, the preview does only work for the first previewed file.

Extension Version: 0.8.3
Version: 1.33.1 (user setup)
Commit: 51b0b28134d51361cf996d2f0a1c698247aeabd8
Date: 2019-04-11T08:27:14.102Z
Electron: 3.1.6
Chrome: 66.0.3359.181
Node.js: 10.2.0
V8: 6.6.346.32
OS: Windows_NT x64 10.0.17763

Preview not working on Linux

Awesome extension, works great on Windows. Getting the following error trying to open one of the demo shaders on Linux.

[Embedded Page] Uncaught TypeError: Cannot read property 'getExtension' of null

Pause button and frame time show up, but no shader view.

This on Linux Deepin 15.8.
VSCode version info:
Version: 1.29.1
Commit: bc24f98b5f70467bc689abf41cc5550ca637088e
Date: 2018-11-15T19:07:43.495Z
Electron: 2.0.12
Chrome: 61.0.3163.100
Node.js: 8.9.3
V8: 6.1.534.41
Architecture: x64

[proposal] Add full screen support

This is a very impressive plugin, and I had a lot of fun with it! However, if the preview has the full-screen feature, it can even be used as a screen saver.

Start using Webview API

We're using vscode.previewHtml, but that has been deprecated. One can see it every time one launches a debug session of the extension.
So instead we should use the Webview API. Some more details are here: https://go.microsoft.com/fwlink/?linkid=2039309

I haven't taken a closer look yet, so I don't know what kind of refactor would be required.

GLSL viewer suddenly not loading

Hey there, see image below. This happens after trying to open the GLSL viewer on a file that has worked previously. As you can see there is no error log displayed as usual - only grey boxes. Not sure what else to try or where to go from here. Thanks in advance for the help.

Screen Shot 2019-03-31 at 4 03 13 am

Feature Request: Keyboard Input

Just as shadertoy.com we should support keyboard input. Ideally we would have the same interface (e.g. a 256x3 texture specifying:

  1. the js keycode on x,
  2. on y == 0 a toggle,
  3. on y == 1 a pressed (this frame),
  4. on y == 2 a down (as in button is held).

I personally miss a release (this frame), which we could support optionally by a setting.

Additionally I think we should inject code for querying the key-states for ease of use. Unless anyone has an idea why shadertoy.com does not allow that.

Play / Stop Preview

Hi There

I'm using the extension to try shaders like on shadertoy. I think a play / stop button for the preview would be nice. Now it's always trying to complie, but I had moments when some thing heavy was beeing processed and I couldn't bearly move the cursor. So I had to type an error to stop the preview :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.