React Regl Component

Sun Sep 25 2022
REGL
SHADER

A Regl component

What

A implementation of a REGL component. REGL is a declarative WebGL library for javascript. This is an implementation of that library in a React component.

Demo

I have posted a demo on Stackblitz.


Dependancies

  • Regl
  • Typescript (optional)

App.tsx

As most application the 'entry point' can be found in app.tsx

The basics


We will need to render a canvas element and have a ref to the element.

export default function App() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  
  ...
  return <canvas ref={canvasRef}></canvas>;
}


Shader


We will need to have a shader for our Regl frame to render. I created a basic shader to render the UV coordinates. And export it from shader.js.

import fragmentShader from './shaders/shader.js';


And the shader itself.

export default `precision mediump float;
uniform vec4 color;
uniform vec2 u_resolution;


void main() {
    vec2 uv = gl_FragCoord.xy/u_resolution.xy;
    gl_FragColor = vec4(uv,.0,1);
}`;



useEffect


We will need to initialise the Regl frame once the component has been mounted. We will use the useEffect hook for that.

useEffect(() => {
    const canvas = canvasRef.current;


    if (!canvas) {
      return;
    }


    var reglObj = regl({
      canvas: canvas,
    });


    // regl.frame() wraps requestAnimationFrame and also handles viewport changes
    reglObj.frame(({ time }) => {
      // clear contents of the drawing buffer
      reglObj.clear({
        color: [0, 0, 0, 0],
        depth: 1,
      });


      reglObj({
        // Shaders in regl are just strings.  You can use glslify or whatever you want
        // to define them.  No need to manually create shader objects.
        frag: fragmentShader,


        vert: `
                  precision mediump float;
                  attribute vec2 position;
                  void main() {
                    gl_Position = vec4(position, 0, 1);
                  }`,


        // Here we define the vertex attributes for the above shader
        attributes: {
          // regl.buffer creates a new array buffer object
          position: [
            [-1, -1], // no need to flatten nested arrays, regl automatically
            [1, -1], // unrolls them into a typedarray (default Float32)
            [1, 1],


            [1, 1],
            [-1, 1],
            [-1, -1],
          ],
          // regl automatically infers sane defaults for the vertex attribute pointers
        },


        uniforms: {
          // This defines the color of the triangle to be a dynamic variable
          u_resolution: [canvas.width, canvas.height],
        },


        // This tells regl the number of vertices to draw in this command
        count: 6,
      })();
    });


    //cleanup
    return () => {
      reglObj.destroy();
    };
  }, []);


Conclusion

At this point you should have a basic Regl frame component. You should be able to uplift the vertex shader. Although I only plan to use it as a playground for fragment shaders.