Update shaders (#73)
* max grid-size from 32 to 256 & support shadertoy-shader format * max grid-size from 32 to 256 & support shadertoy-shader format * fix shader loader * update css-doodle.min * fix test-case
This commit is contained in:
parent
3888b82312
commit
01d0fac7d5
|
|
@ -165,7 +165,7 @@
|
|||
return array[array.length - 1];
|
||||
}
|
||||
|
||||
function scan(source) {
|
||||
function scan(source, preserveLineBreak = false) {
|
||||
let iter = iterator$1(String(source).trim());
|
||||
let tokens = [];
|
||||
let quoteStack = [];
|
||||
|
|
@ -240,7 +240,7 @@
|
|||
if (ignoreLeft || ignoreRight) {
|
||||
continue;
|
||||
} else {
|
||||
spaces = ' ';
|
||||
spaces = preserveLineBreak ? curr : ' ';
|
||||
}
|
||||
}
|
||||
if (tokens.length && (next && next.trim())) {
|
||||
|
|
@ -1200,7 +1200,7 @@
|
|||
return Tokens;
|
||||
}
|
||||
|
||||
const [ min, max, total ] = [ 1, 32, 32 * 32 ];
|
||||
const [ min, max, total ] = [ 1, 256, 256 * 256 ];
|
||||
|
||||
function parse_grid(size) {
|
||||
let [x, y, z] = (size + '')
|
||||
|
|
@ -1225,7 +1225,8 @@
|
|||
}
|
||||
|
||||
function parse$7(input) {
|
||||
let iter = iterator$1(removeParens(scan(input)));
|
||||
input = input.replace(/\/\/[^\n]*(\n|$)/mg, ''); // remove single-line comment
|
||||
let iter = iterator$1(removeParens(scan(input, true)));
|
||||
let stack = [];
|
||||
let tokens = [];
|
||||
let identifier;
|
||||
|
|
@ -4303,8 +4304,10 @@
|
|||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, image);
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
}
|
||||
|
|
@ -4326,12 +4329,37 @@
|
|||
|
||||
// resolution uniform
|
||||
let fragment = add_uniform(shaders.fragment || '', 'uniform vec2 u_resolution;');
|
||||
|
||||
fragment = add_uniform(fragment, 'uniform float u_time;');
|
||||
fragment = add_uniform(fragment, 'uniform float u_timeDelta;');
|
||||
fragment = add_uniform(fragment, 'uniform int u_frameIndex;');
|
||||
// fragment = add_uniform(fragment, 'uniform vec4 u_mouse;');
|
||||
|
||||
// texture uniform
|
||||
shaders.textures.forEach(n => {
|
||||
let uniform = `uniform sampler2D ${ n.name };`;
|
||||
fragment = add_uniform(fragment, uniform);
|
||||
});
|
||||
|
||||
const isShaderToyFragment = /(^|[^\w\_])void\s+mainImage\(\s*out\s+vec4\s+fragColor,\s*in\s+vec2\s+fragCoord\s*\)/mg.test(fragment);
|
||||
|
||||
if(isShaderToyFragment) {
|
||||
fragment = `// https://www.shadertoy.com/howto
|
||||
|
||||
#define iResolution vec3(u_resolution, 0)
|
||||
#define iTime u_time
|
||||
#define iTimeDelta u_timeDelta
|
||||
#define iFrame u_frameIndex
|
||||
|
||||
${shaders.textures.map((n, i) => `#define iChannel${i} ${n.name}`).join('\n')}
|
||||
|
||||
${fragment}
|
||||
|
||||
void main() {
|
||||
mainImage(FragColor, gl_FragCoord.xy);
|
||||
}`;
|
||||
}
|
||||
|
||||
let program = create_program(
|
||||
gl,
|
||||
shaders.vertex || default_vertex_shader,
|
||||
|
|
@ -4367,10 +4395,19 @@
|
|||
|
||||
// resolve image data in 72dpi :(
|
||||
const uTimeLoc = gl.getUniformLocation(program, "u_time");
|
||||
if(uTimeLoc) {
|
||||
const uFrameLoc = gl.getUniformLocation(program, "u_frameIndex");
|
||||
const uTimeDelta = gl.getUniformLocation(program, "u_timeDelta");
|
||||
if(uTimeLoc || uFrameLoc) {
|
||||
let frameIndex = 0;
|
||||
let currentTime = 0;
|
||||
return Promise.resolve(Cache.set(shaders, (t) => {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.uniform1f(uTimeLoc, t / 1000);
|
||||
if(uTimeLoc) gl.uniform1f(uTimeLoc, t / 1000);
|
||||
if(uFrameLoc) gl.uniform1i(uFrameLoc, frameIndex++);
|
||||
if(uTimeDelta) {
|
||||
gl.uniform1f(uTimeDelta, (currentTime - t) / 1000);
|
||||
currentTime = t;
|
||||
}
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
return canvas.toDataURL();
|
||||
}));
|
||||
|
|
@ -5225,7 +5262,7 @@
|
|||
}
|
||||
};
|
||||
requestAnimationFrame(update);
|
||||
const ret = value();
|
||||
const ret = value(0);
|
||||
element.style.backgroundImage = `url(${ret})`;
|
||||
currentImage = element.style.backgroundImage;
|
||||
return '';
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -49,8 +49,10 @@ function load_texture(gl, image, i) {
|
|||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, image);
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
}
|
||||
|
|
@ -72,12 +74,37 @@ function draw_shader(shaders, width, height) {
|
|||
|
||||
// resolution uniform
|
||||
let fragment = add_uniform(shaders.fragment || '', 'uniform vec2 u_resolution;');
|
||||
|
||||
fragment = add_uniform(fragment, 'uniform float u_time;');
|
||||
fragment = add_uniform(fragment, 'uniform float u_timeDelta;');
|
||||
fragment = add_uniform(fragment, 'uniform int u_frameIndex;');
|
||||
// fragment = add_uniform(fragment, 'uniform vec4 u_mouse;');
|
||||
|
||||
// texture uniform
|
||||
shaders.textures.forEach(n => {
|
||||
let uniform = `uniform sampler2D ${ n.name };`;
|
||||
fragment = add_uniform(fragment, uniform);
|
||||
});
|
||||
|
||||
const isShaderToyFragment = /(^|[^\w\_])void\s+mainImage\(\s*out\s+vec4\s+fragColor,\s*in\s+vec2\s+fragCoord\s*\)/mg.test(fragment);
|
||||
|
||||
if(isShaderToyFragment) {
|
||||
fragment = `// https://www.shadertoy.com/howto
|
||||
|
||||
#define iResolution vec3(u_resolution, 0)
|
||||
#define iTime u_time
|
||||
#define iTimeDelta u_timeDelta
|
||||
#define iFrame u_frameIndex
|
||||
|
||||
${shaders.textures.map((n, i) => `#define iChannel${i} ${n.name}`).join('\n')}
|
||||
|
||||
${fragment}
|
||||
|
||||
void main() {
|
||||
mainImage(FragColor, gl_FragCoord.xy);
|
||||
}`
|
||||
}
|
||||
|
||||
let program = create_program(
|
||||
gl,
|
||||
shaders.vertex || default_vertex_shader,
|
||||
|
|
@ -113,10 +140,19 @@ function draw_shader(shaders, width, height) {
|
|||
|
||||
// resolve image data in 72dpi :(
|
||||
const uTimeLoc = gl.getUniformLocation(program, "u_time");
|
||||
if(uTimeLoc) {
|
||||
const uFrameLoc = gl.getUniformLocation(program, "u_frameIndex");
|
||||
const uTimeDelta = gl.getUniformLocation(program, "u_timeDelta");
|
||||
if(uTimeLoc || uFrameLoc) {
|
||||
let frameIndex = 0;
|
||||
let currentTime = 0;
|
||||
return Promise.resolve(Cache.set(shaders, (t) => {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.uniform1f(uTimeLoc, t / 1000);
|
||||
if(uTimeLoc) gl.uniform1f(uTimeLoc, t / 1000);
|
||||
if(uFrameLoc) gl.uniform1i(uFrameLoc, frameIndex++);
|
||||
if(uTimeDelta) {
|
||||
gl.uniform1f(uTimeDelta, (currentTime - t) / 1000);
|
||||
currentTime = t;
|
||||
}
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
return canvas.toDataURL();
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ if (typeof customElements !== 'undefined') {
|
|||
}
|
||||
};
|
||||
requestAnimationFrame(update);
|
||||
const ret = value();
|
||||
const ret = value(0);
|
||||
element.style.backgroundImage = `url(${ret})`;
|
||||
currentImage = element.style.backgroundImage;
|
||||
return '';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { clamp } from '../utils/index.js';
|
||||
|
||||
const [ min, max, total ] = [ 1, 32, 32 * 32 ];
|
||||
const [ min, max, total ] = [ 1, 256, 256 * 256 ];
|
||||
|
||||
export default function parse_grid(size) {
|
||||
let [x, y, z] = (size + '')
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import { scan, iterator, Token } from './tokenizer.js';
|
|||
import { is_empty } from '../utils/index.js';
|
||||
|
||||
function parse(input) {
|
||||
let iter = iterator(removeParens(scan(input)));
|
||||
input = input.replace(/\/\/[^\n]*(\n|$)/mg, ''); // remove single-line comment
|
||||
let iter = iterator(removeParens(scan(input, true)));
|
||||
let stack = [];
|
||||
let tokens = [];
|
||||
let identifier;
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ function last(array) {
|
|||
return array[array.length - 1];
|
||||
}
|
||||
|
||||
function scan(source) {
|
||||
function scan(source, preserveLineBreak = false) {
|
||||
let iter = iterator(String(source).trim());
|
||||
let tokens = [];
|
||||
let quoteStack = [];
|
||||
|
|
@ -233,7 +233,7 @@ function scan(source) {
|
|||
if (ignoreLeft || ignoreRight) {
|
||||
continue;
|
||||
} else {
|
||||
spaces = ' ';
|
||||
spaces = preserveLineBreak ? curr : ' ';
|
||||
}
|
||||
}
|
||||
if (tokens.length && (next && next.trim())) {
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ test('clamp value', t => {
|
|||
|
||||
compare(t, '0x1', defaultGrid);
|
||||
|
||||
compare(t, '2000,1', { x: 1024, y: 1, z: 1, count: 1024, ratio: 1024 });
|
||||
compare(t, '70000,1', { x: 65536, y: 1, z: 1, count: 65536, ratio: 65536 });
|
||||
|
||||
compare(t, '2000', { x: 32, y: 32, z: 1, count: 1024, ratio: 1 });
|
||||
compare(t, '70000', { x: 256, y: 256, z: 1, count: 65536, ratio: 1 });
|
||||
|
||||
compare(t, '0.5', defaultGrid);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ test('should break line on #define ', t => {
|
|||
void main() {}
|
||||
`;
|
||||
let result = {
|
||||
fragment: '\n#define CONST2\n void main(){}',
|
||||
fragment: '\n#define CONST2\n\nvoid main(){}',
|
||||
textures: []
|
||||
}
|
||||
compare(t, input, result);
|
||||
|
|
|
|||
Loading…
Reference in New Issue