更新履歴
- 2021-11-16 backbufferとマウスの対応
- 2023-05-02 twigl(classic 300es)について追記
ShadertoyのコードをGLSL Sandboxに一発で移植するコードを思いつきました。
以下のコードをShadertoyのコードの先頭にコピペするだけで、元のコードには一切手を加えずにGLSL Sandbox用のコードに変換できます。
// BEGIN: shadertoy porting template
// https://gam0022.net/blog/2019/03/04/porting-from-shadertoy-to-glslsandbox/
precision highp float;
uniform vec2 resolution;
uniform float time;
uniform vec2 mouse;
uniform sampler2D backbuffer;
#define iResolution resolution
#define iTime time
#define iMouse (vec4(mouse, 0.5, 0.5) * resolution.xyxy)
#define iChannel0 backbuffer
#define texture texture2D
void mainImage(out vec4 fragColor, in vec2 fragCoord);
void main(void) {
vec4 col;
mainImage(col, gl_FragCoord.xy);
gl_FragColor = col;
}
// END: shadertoy porting template
Shadertoyのマルチパスやテクスチャ機能をつかったShaderの移植はできませんが、普通の1パスのShaderなら移植できると思います。
ぜひ使ってみてください!
Shadertoy → NEORT の移植事例
最近、NEORTという国内産Shadertoyのようなサイトが登場しました。
NEORTはGLSL Sandbox互換があるので、ご紹介した方法で一発でShadertoyから移植できました。
NEORTはじめました⛩️#GLSL #creativecoding https://t.co/acKyzwIU8S pic.twitter.com/1AqphUQ5jv
— がむ (@gam0022) 2019年2月27日
Shadertoy → twigl (classic 300es)
SESSION 2023のGLSL Graphics Compoではtwiglが採用されたので、twigl対応をしました。
"Transcendental Cube"
— がむ (@gam0022) May 1, 2023
2nd place at GLSL Graphics Compo, #SESSIONS_Party 2023 🥈
SESSIONS 2023のGLSL Graphics Compoで2位を勝ち取りました! pic.twitter.com/Ra2Y0Ccfpx
// BEGIN: shadertoy porting template
// https://gam0022.net/blog/2019/03/04/porting-from-shadertoy-to-glslsandbox/
precision highp float;
uniform vec2 resolution;
uniform float time;
uniform vec2 mouse;
uniform sampler2D backbuffer;
#define iResolution resolution
#define iTime time
#define iMouse (vec4(mouse, .5, .5) * resolution.xyxy)
#define iChannel0 backbuffer
void mainImage(out vec4 fragColor, vec2 fragCoord);
out vec4 outColor;
void main () {
vec4 col;
mainImage(col, gl_FragCoord.xy);
outColor = col;
}
// END: shadertoy porting template
解説
なぜこれでうまく移植できるのか、簡単に解説します。
uniform名の違いの吸収
まず以下のコードでShadertoyとGLSL Sandboxのuniform名の違いの吸収しています。
単純に #define
のプリプロセッサで置換しているだけなので、特に不思議なことは無いと思います。
uniform vec2 resolution;
uniform float time;
uniform vec2 mouse;
#define iResolution resolution
#define iTime time
#define iMouse mouse
エントリーポイント名の違いの吸収
Shadertoyのエントリポイントは mainImage
で、GLSL Sandboxは main
です。
が、よく考えてみると、ShadertoyもWebGLで実装されているからにはGLSLのルールに従って main
が定義されているはずです。
Shadertoyのソースコードを眺めてみると、mainImage
を呼び出す main
関数をヘッダーとして挿入する実装になっています。
void main(void) {
vec4 col;
mainImage(col, gl_FragCoord.xy);
gl_FragColor = col;
}
この「mainImage を呼び出す main を定義する」というアイデアはkanetaさんのこの作品からヒントをもらいました!
早速2D版🤔のGLSLコード置いているので、ご自由にお使いください🤔https://t.co/OJjTYlLy0c pic.twitter.com/NYN6zT77sM
— かねた (@kanetaaaaa) 2019年2月23日
次はコンパイルエラーを避けるための前方宣言です。
void mainImage(out vec4 fragColor, in vec2 fragCoord);
GLSLではC言語と同様に、別の関数から呼び出される前に関数を定義するか、前方宣言する必要があります。