regl icon indicating copy to clipboard operation
regl copied to clipboard

live-coding

Open brucelane opened this issue 8 years ago • 11 comments

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 avatar Jan 20 '17 07:01 brucelane

@brucelane how are you constructing and using your regl command?

jwerle avatar Jan 26 '17 21:01 jwerle

I'm just trying it online ( http://regl.party/examples/?basic )

brucelane avatar Jan 27 '17 03:01 brucelane

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 :)

ghost avatar Jan 27 '17 18:01 ghost

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.

ghost avatar Jan 27 '17 20:01 ghost

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 avatar Jan 27 '17 21:01 brucelane

@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

bmFicg avatar Jan 29 '17 15:01 bmFicg

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

gre avatar Jul 26 '17 14:07 gre

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)

gre avatar Jul 26 '17 15:07 gre

sounds good, going to try it soon, once I'm less busy with a vuejs project ...

brucelane avatar Jul 26 '17 19:07 brucelane

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!

1wheel avatar Sep 14 '17 04:09 1wheel

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.

mattdesl avatar Dec 22 '17 16:12 mattdesl