1. 环境配置
1.1 下载对应插件
1.2 配置 GLSL-Linter 库
1.2.1 下载 VsCode 的 glsl 依赖包
https://github.com/KhronosGroup/glslang/releases
- 下载
glslang-master-windows-x64-Release.zip
1.2.2 在 VsCode 中配置路径
- 点击左下角齿轮,点击
Settings
- 打开界面后,点击左侧
Extensions
,选择GLSL linter configuration
- 设置路径
Glsl-linter:Validator Path
,指向glslangValidator.exe
- 按
Ctrl
+Shift
+P
打开设置(json),添加如下代码:
1 | "glsl-linter.validatorPath": "D:\\WorkInstaller\\OpenGL\\glslang\\glslang\\bin\\glslangValidator.exe", |
1.3 配置代码提示
输入 glsl
,进入配置界面:
在配置界面配置代码提示:
配置下载地址:
https://github.com/mdyshad0w/glslsnippets
2. 从 ShaderToy 到 VsCode
具体参考 VsCode 上的 ShaderToy 插件提供的官方文档:
2.1 从 ShaderToy 上爬取资源
主要是爬取对应的纹理资源
脚本下载地址:
https://github.com/What-a-stupid-username/ShaderToyHelper
运行后在控制台输入对应网址或者ID号:
- 例如:
https://www.shadertoy.com/view/4dSBDt
或者4dSBDt
文件将直接下载至当前文件夹
注意修改对应的后缀:
- 比如说
code.txt
改为glsl
等等
2.2 配置通道的输入
在 ShaderToy
上的项目,每个项目会有若干个通道输入,例如:
2.2.1 纹理输入
图片输入
1 | // 使用相对路径读取本地图片 |
着色器输入
1 | #iChannel0 "./buf B.glsl" |
当前着色器的最后一帧作为输入
1 | #iChannel0 "self" |
Note :
- 纹理大小必须是 2 的幂次方
- 使用相对路径输入时,需要使用 VsCode 点开整个文件夹
2.2.2 Cubemap 输入
1 | // 注意需要 {} |
实际使用中 Cubemaps 可以指定为任何其他纹理(例如 .jpg
),通过包含通配符的路径和显式声明的类型的组合,识别出这个通道是一个 Cubemaps
通配符将通过替换以下任意集合中的值来解析
- [ ‘e’, ‘w’, ‘u’, ‘d’, ‘n’, ‘s’ ]
- [ ‘east’, ‘west’, ‘up’, ‘down’, ‘north’, ‘south’ ]
- [ ‘px’, ‘nx’, ‘py’, ‘ny’, ‘pz’, ‘nz’ ]
- [ ‘posx’, ‘negx’, ‘posy’, ‘negy’, ‘posz’, ‘negz’ ]
如果找不到这六个文件中的任何一个,则从第一个文件开始尝试下一个文件集
2.2.3 音频输入
1 | #iChannel0 "./music/epic.mp3" |
- 如果通道定义了音频输入,它将从文件扩展名中推断出来
- 通道将是一个 2×512 像素的纹理(高×宽),宽度可以通过
Audio Domain Size
设置来进行调整 - 第一行包含音频频谱,第二行包含其波形
Note :
- 默认情况下音频输入是禁用,需要手动去设置中启用
Enable Audio Input
2.2.4 输入的采样标准设置
在 VsCode 中进行如下设置
1 | #iChannel0::MinFilter "NearestMipMapNearest" |
2.2.5 键盘输入
在着色器前声明:
1 | #iKeyboard |
此时暴露给着色器以下功能:
1 | bool isKeyPressed(int); |
同时也提供一些变量与上述函数组合使用来查询键盘事件:
Key_A
to Key_Z
, Key_0
to Key_9
, Key_UpArrow
, Key_LeftArrow
, Key_Shift
2.3 导入其他的着色器
使用如下语法导入其他着色器作为库来使用:
1 |
Note :
- 显然,这些着色器不允许定义
void main()
函数,只能定义一些常量和运算函数
2.4 Uniforms 变量
2.4.1 内置的 Uniforms 变量
iResolution
iGlobalTime
(also asiTime
)iTimeDelta
iFrame
iMouse
iMouseButton
iDate
iSampleRate
iChannelN
( N in [0, 9] )iChannelResolution[]
2.4.2 自定义的 Uniforms 变量
使用自定义的 Uniforms 变量定义那些直接在着色器中使用的 Uniforms 变量,给一个初始值以及一个范围
1 | // 暴露一个滑动条来编辑该值 |
3. 与 ShaderToy 的兼容性
Example :
1 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. |
其中做了如下替换:
gl_FragCoord
->fragCoord
gl_FragColor
->fragColor
其中 void main()
将委托给 void mainImage(out vec4, in vec2)
函数:
void main()
的定义是通过匹配/void\s+main\s*\(\s*\)\s*\{/g
找到的;- 除了定义扩展生成的定义以外,还需定义
void main()
,可以定义成void main(void)
。
例如,如果您的主定义将由预处理器处理掉,因此扩展不应该获取,那么这可能是必要的。
由于兼容性是通过一个简单的regex匹配实现的,所以它只是半可靠的。
如果只使用 shadertoy.com 网站执行诸如通过宏定义 mainImage
之类的操作时,您可能希望启用 “Shader Toy Strict Compatibility” 设置,该设置禁用使用定义 void main()
的着色器的功能,并且只允许以某种方式定义 mainImage
的着色器。
或者,您可以在着色器中使用 #StrictCompatibility
将此功能本地化为该着色器。
4. glslify 的集成
您可以在设置中启用对 glslify
的支持,但由于 glslify
不支持转换前后的行映射,因此只要启用该设置,错误行号将被禁用。使用 glslify
允许使用 node.js
风格的模块系统:
1 | #pragma glslify: snoise = require('glsl-noise/simplex/2d') |