regl
regl copied to clipboard
live-coding
Hi, regl is great!
I would like to use regl to live-code shaders, unfortunately the screen switches to black at each keystroke, I guess it's the compilation time?
Or am I missing something? Thank you Bruce
@brucelane how are you constructing and using your regl command?
I'm just trying it online ( http://regl.party/examples/?basic )
If you set up regl locally with a live-reloading server (webpack/browserSync) then you should be able to have your code editor window on one side, and your browser window on the other and do some live coding. You also won't have to rely on an internet connection :)
If you use a tool like budo you can run it in --live
mode. When you save the file locally, the page updates. There will be a flash when you save the file to do a reload, but that should be better than a flash for every keystroke.
Otherwise, you (or somebody) will have to write a wrapper around regl for a tool like browserify-hmr.
I really appreciate webpack, gulp or other tools to reload the page, but in live coding I need an editor which only redraws the result if the shader compiles to keep the audience "captivated" ;-)
@brucelane type an error somewhere in your code, will refuse the online editor (at regl.party) from refresh i do +++ and then comment/uncomment Simple and convenient
I guess it would be possible to implement such https://webpack.github.io/docs/hot-module-replacement.html maybe it could be a lib too
here is an example with webpack:
shaders/render.js:
module.exports = regl =>
regl({
frag: `
precision mediump float;
uniform vec4 color;
varying vec2 uv;
void main() {
gl_FragColor = vec4(uv, color.b, color.a);
}`,
vert: `
precision mediump float;
attribute vec2 position;
varying vec2 uv;
void main() {
gl_Position = vec4(position, 0, 1);
uv = (position + 1.0) / 2.0;
}`,
attributes: {
position: regl.buffer([[-1, -1], [-1, 4], [4, -1]])
},
uniforms: {
color: regl.prop("color")
},
count: 3
});
main.js:
import createREGL from "regl";
import renderShader from "./shaders/render";
...
const gl =
canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
const regl = createREGL(gl);
let render = renderShader(regl);
if (module.hot) {
module.hot.accept("./shaders/render", () => {
render = require("./shaders/render")(regl);
});
}
regl.frame(({ time }) => {
regl.clear({
color: [0, 0, 0, 0],
depth: 1
});
render({
color: [
Math.cos(time * 0.1),
Math.sin(time * 0.8),
Math.cos(time * 0.3),
1
]
});
});
it's a bit specific but i'm pretty sure it could be made more generic? anyway at least it does the job of hotswapping just the shader part that changes (when editing shaders/render.js, only that part get reloaded)
sounds good, going to try it soon, once I'm less busy with a vuejs project ...
Webpack is too heavy and confusing for me; I hacked this together with hot-server to update code without a hard refresh. Making tweaks is way easier if you can see the before and after right next to each other!
I just released shader-reload which I'm using with budo to achieve live editing of shaders. It involves splitting them into a separate module and attaching a transform on the browserify dev server. When editing the .shader.js
files, they will get live-updated, and any other files will trigger a regular browser reload.
It looks a bit like this. Regl handles the updates smoothly since it will check for source code differences and re-compile if necessary before rendering.
src/index.js
const regl = require('regl')(document.body);
const shader = require('./blue.shader');
let draw = regl({
frag: () => shader.fragment,
vert: () => shader.vertex,
...
});
regl.frame(() => {
...
draw();
});
src/blue.shader.js
module.exports = require('shader-reload')({
vertex: '... shader source string ...',
fragment: '... shader source string ...'
});
One minor point of annoyance with regl is that when a program fails (e.g. syntax error), it spits out console errors every frame until the program error is resolved.