···
+
const VERSION_300 = '#version 300 es';
'attribute vec2 vPos;\n' +
' gl_Position = vec4(vPos, 0.0, 1.0);\n' +
' gl_Position = vPos;\n' +
···
DATE.getMilliseconds() * 0.001;
return [year, month, day, time] as const;
+
const preprocessShader = (source: string, isES300: boolean) => {
+
if (output.startsWith(VERSION_300)) {
+
output = output.slice(VERSION_300.length + 1);
+
header += `${VERSION_300}\n`;
+
if (!/^\s*precision /.test(output)) header += 'precision highp float;\n';
+
if (output.includes('iChannel0')) header += 'uniform sampler2D iChannel0;\n';
+
if (output.includes('iResolution')) header += 'uniform vec2 iResolution;\n';
+
if (output.includes('iChannelResolution'))
+
header += 'uniform vec3 iChannelResolution[1];\n';
+
if (output.includes('iTime')) header += 'uniform float iTime;\n';
+
if (output.includes('iTimeDelta')) header += 'uniform float iTimeDelta;\n';
+
if (output.includes('iFrame')) header += 'uniform float iFrame;\n';
+
if (output.includes('iChannel')) header += 'uniform float iChannel;\n';
+
if (output.includes('iDate')) header += 'uniform vec4 iDate;\n';
+
if (isES300 && output.includes('gl_FragColor'))
+
header += 'out vec4 gl_FragColor;\n';
+
if (isES300 && output.includes('gl_FragCoord'))
+
header += 'in vec2 gl_FragCoord;\n';
+
if (!/main\s*\(/.test(output)) {
+
const ioRe = /\(\s*out\s+vec4\s+(\S+)\s*,\s*in\s+vec2\s+(\S+)\s*\)/g;
+
const io = ioRe.exec(source);
+
output = output.replace(/mainImage\s*\(/, 'main(').replace(ioRe, '()');
+
if (io && io[1] !== 'gl_FragColor')
+
header += `#define ${io[1]} gl_FragColor\n`;
+
if (io && io[2] !== 'gl_FragCoord')
+
header += `#define ${io[2]} gl_FragCoord.xy\n`;
+
if (!isES300) output = output.replace(/texture\s+\(/g, 'texture2D(');
+
return `${header}\n${output}`;
···
updateFragShader(fragSource: string) {
fragSource = fragSource.trim();
+
const isES300 = /\s+#version 300/i.test(fragSource);
+
gl.shaderSource(fragShader, preprocessShader(fragSource, isES300));
gl.compileShader(fragShader);
+
const vertShader = isES300 ? vertShader300 : vertShader100;
gl.attachShader(program, vertShader);
gl.attachShader(program, fragShader);