这个扩展能够在 VSCode 中查看 GLSL 着色器的 WebGL 实时预览,经过提供 “Show GLSL Preview” 命令能够达到相似于访问 shadertoy.com 的效果。node
要运行该命令,能够打开 “Command Palette” 并输入“ Shader Toy: Show GLSL Preview ”,或者在文本编辑器中右键单击并从上下文菜单中选择 “Shader Toy: Show GLSL Preview” 。git
运行该命令将视图分割并显示一个应用了您的着色器的全屏四方的视图。您的片断着色器的入口点是 void main() ,或者若是前者不可用,那么入口点则是 void mainImage(vec4 out,vec2 in) ,其中第一个参数是输出颜色,第二个参数是片断屏幕位置。github
另外一个可用的命令是 “Shader Toy: Show Static GLSL Preview” ,它将打开一个预览,但不会对变化的编辑器做出反应。能够一次打开任意数量的编辑视图,这使得依赖于多个通道的着色器能够被一个惟一的工做流进行编辑。浏览器
目前,iResolution、iGlobalTime(也称 iTime)、iTimeDelta、iFrame、iMouse、iMouseButton、iDate、iSampleRate、iChannelN (其中 N 在 [0,9] 区间内)和 iChannelResolution[] 都是可用的 uniform 变量。安全
纹理通道 iChannelN 能够经过在着色器顶部插入以下形式的代码来定义服务器
#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"
复制代码
以上代码演示了markdown
注意,要使用本地输入的相对路径,您必须在可视代码中打开一个文件夹。app
纹理示例为了影响纹理的采样行为,使用如下语法:编辑器
#iChannel0::MinFilter "NearestMipMapNearest"
#iChannel0::MagFilter "Nearest"
#iChannel0::WrapMode "Repeat"
复制代码
注意,由于 WebGL 标准,许多选项只能在宽度和高度都是 2 的幂次状况下工做。函数
Cubemaps 能够指定为任何其余纹理,事实上,它们是 Cubemaps 的路径包含通配符和它们的类型被显式声明的组合。
#iChannel0 "file://cubemaps/yokohama_{}.jpg" // 注意 '{}'
#iChannel0::Type "CubeMap"
复制代码
通配符将经过替换下列集合中的任何值来解析
若是找不到这六个文件中的任何一个,就从下一个集合的第一个开始尝试。
注意: 默认状况下音频输入是禁用的,更改设置 “Enable Audio Input” 来启用它。
不支持音频输入从内部_Visual Studio代码,由于ffmpeg不是附带Visual Studio代码,因此您必须生成一个独立的版本和主机本地服务器可以加载本地文件(或摆弄你的浏览器安全设置)若是您想要在着色器使用音频的话。若是您的通道定义了音频输入,它将从文件扩展名中推断出来。通道将是一个 2 像素高和 512 像素宽的纹理,宽度能够经过“Audio Domain Size” 设置来调整。第一行包含音频频谱,第二行包含其波形。
若是你想使用键盘输入,你能够在着色器前加上 #iKeyboard。这将暴露给你的着色器如下功能:
bool isKeyPressed(int);
bool isKeyReleased(int);
bool isKeyDown(int);
bool isKeyToggled(int);
复制代码
此外,它还将暴露从 Key_A 到 Key_Z、从 Key_0 到 Key_9、Key_UpArrow、Key_LeftArrow、Key_Shift 等变量。使用这些常量和上面提到的函数来查询键盘的状态。
你也能够经过一个标准的 c 类语法来包括其余文件到你的着色器中:
#include "some/shared/code.glsl"
#include "other/local/shader_code.glsl"
#include "d:/some/global/code.glsl"
复制代码
注意:这些着色器不能定义void main() 函数,所以只能用于工具函数、常量定义等。
使用自定义 uniform 变量定义那些直接在你的着色器中使用的 uniform 变量,给一个初始值以及一个可选的范围。
#iUniform float my_scalar = 1.0 in { 0.0, 5.0 } // 这将暴露一个滑动条来编辑该值
#iUniform float my_discreet_scalar = 1.0 in { 0.0, 5.0 } step 0.2 // 步长为 0.2
#iUniform float other_scalar = 5.0 // 这将公开一个文本字段以给出任意值
#iUniform vec2 position_in_2d = vec2(1.0) // 暴露两个文本字段
#iUniform color3 my_color = color3(1.0) // 这将是一个可编辑的颜色选择器
#iUniform vec4 other_color = vec4(1.0) in { 0.0, 1.0 } // 这将暴露四个滑块
复制代码
下面是一个从 shadertoy.com 移植的 shader 的例子:
// 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);
}
复制代码
注意,与 shadertoy.com 相比,gl_FragCoord 代替了 fragCoord, gl_FragColor 代替了原始演示中的 fragColor。可是,对于插入一个简单的 void main() 有一个基本的支持,它将委托给一个 void mainImage(vec4 out,vec2 in) 函数。void main() 的定义是经过匹配 regex /void\s+main\s (\s)\s*{/g** 找到的,所以,若是除了扩展生成的定义以外还须要定义 void main() ,则能够将其定义为 void main(void) 。例如,若是您的 main 定义将被预处理器处理掉,并所以扩展不接受该定义,则可能有必要这么作。
英文原文: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.
您能够在设置中启用对 glslify 的支持,可是由于 glslify 不支持转换先后的行映射,因此只要启用了设置,就会遗憾地禁用错误上的行号。使用 glslify 容许为您的着色器使用 node.js 风格的模块系统:
#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预览中提供了一个暂停按钮来中止时间的前进。与此相结合,您可使用 GLSL 预览中提供的屏幕快照按钮来捕获和保存帧。默认状况下,保存的屏幕截图的分辨率与 GLSL 预览的分辨率相同的,不过有一个设置容许用户使用任意值覆盖该分辨率。最后,扩展提供了一个关于着色器性能和内存消耗的浅显视图。
该扩展还支持在文本编辑器中突出显示编译错误,对于单个着色器也是如此,对于多个通道的也是如此。它经过在文本编辑器中直接显示做为诊断的错误,以及在 GLSL 预览窗口中以可理解的格式显示错误,并容许用户与错误消息交互跳转到相关行,并在必要时打开相关文件来实现:
获得更多的反馈;
在不可移植的版本中禁用音频;
Cubemap 采样。
任何形式的贡献都是受欢迎和鼓励的。
(略)