OGL WebGL Library

repository·master·Indexed 26 days ago

https://github.com/oframe/ogl

A minimal, effective WebGL library designed for low-level control and minimal abstraction. OGL is ideal for custom shader work and learning WebGL, providing a modular structure consisting of a Math extension of gl-matrix, a Core abstraction layer (including Renderer, Camera, Transform, Geometry, Program, and Mesh), and an Extras layer for advanced functionality.

Tokens
4.3K
Snippets
4
Records
36
Agent score
88%

What's inside ogl

  1. Understand OGL library structure

    master

    OGL is modular and split into three main components:

    1. Math: An extension of gl-matrix providing instancable classes that extend Array. (approx. 6kb minzipped)
    2. Core: The essential WebGL abstraction layer. Includes:
      • Geometry.js
      • Program.js
      • Renderer.js
      • Camera.js
      • Transform.js
      • Mesh.js
      • Texture.js
      • RenderTarget.js
    3. Extras: Additional layers of abstraction for advanced functionality to keep the core lightweight.
  2. Import OGL in your project

    master

    Depending on your environment, you can import OGL in several ways:

    • Local files: Import from the source path.
    • Bundlers/Node Modules: Import directly from the package name.
    • CDN: Use services like jsdelivr, unpkg, or skypack. It is recommended to append a specific version (e.g., @1.0.11) when using a CDN to prevent breaking changes.
    // Local source
    import { ... } from './path/to/src/index.js';
    
    // Bundler / Node modules
    import { ... } from 'ogl';
    
    // CDN
    import { ... } from 'https://cdn.jsdelivr.net/npm/ogl';
    import { ... } from 'https://unpkg.com/ogl';
    import { ... } from 'https://cdn.skypack.dev/ogl';
  3. Render a 3D object (Cube) with OGL

    master

    To render a 3D object, you need a Renderer, a Camera, a Transform (for the scene graph), a Geometry (like Box), a Program (containing your shaders), and a Mesh to combine them.

    import { Renderer, Camera, Transform, Box, Program, Mesh } from 'ogl';
    
    {
        const renderer = new Renderer();
        const gl = renderer.gl;
        document.body.appendChild(gl.canvas);
    
        const camera = new Camera(gl);
        camera.position.z = 5;
    
        function resize() {
            renderer.setSize(window.innerWidth, window.innerHeight);
            camera.perspective({
                aspect: gl.canvas.width / gl.canvas.height,
            });
        }
        window.addEventListener('resize', resize, false);
        resize();
    
        const scene = new Transform();
    
        const geometry = new Box(gl);
    
        const program = new Program(gl, {
            vertex: /* glsl */ `
                attribute vec3 position;
    
                uniform mat4 modelViewMatrix;
                uniform mat4 projectionMatrix;
    
                void main() {
                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                }
            `,
            fragment: /* glsl */ `
                void main() {
                    gl_FragColor = vec4(1.0);
                }
            `,
        });
    
        const mesh = new Mesh(gl, { geometry, program });
        mesh.setParent(scene);
    
        requestAnimationFrame(update);
        function update(t) {
            requestAnimationFrame(update);
    
            mesh.rotation.y -= 0.04;
            mesh.rotation.x += 0.03;
    
            renderer.render({ scene, camera });
        }
    }
  4. Create a full-screen shader with custom geometry

    master

    For simple full-screen effects, you can omit the Camera and Transform components. You can also define custom Geometry using Float32Array for positions and UVs.

    import { Renderer, Geometry, Program, Mesh } from 'ogl';
    
    {
        const renderer = new Renderer({
            width: window.innerWidth,
            height: window.innerHeight,
        });
        const gl = renderer.gl;
        document.body.appendChild(gl.canvas);
    
        // Triangle that covers viewport, with UVs that still span 0 > 1 across viewport
        const geometry = new Geometry(gl, {
            position: { size: 2, data: new Float32Array([-1, -1, 3, -1, -1, 3]) },
            uv: { size: 2, data: new Float32Array([0, 0, 2, 0, 0, 2]) },
        });
        // Alternatively, you could use the Triangle class.
    
        const program = new Program(gl, {
            vertex: /* glsl */ `
                attribute vec2 uv;
                attribute vec2 position;
    
                varying vec2 vUv;
    
                void main() {
                    vUv = uv;
                    gl_Position = vec4(position, 0, 1);
                }
            `,
            fragment: /* glsl */ `
                precision highp float;
    
                uniform float uTime;
    
                varying vec2 vUv;
    
                void main() {
                    gl_FragColor.rgb = vec3(0.8, 0.7, 1.0) + 0.3 * cos(vUv.xyx + uTime);
                    gl_FragColor.a = 1.0;
                }
            `,
            uniforms: {
                uTime: { value: 0 },
            },
        });
    
        const mesh = new Mesh(gl, { geometry, program });
    
        requestAnimationFrame(update);
        function update(t) {
            requestAnimationFrame(update);
    
            program.uniforms.uTime.value = t * 0.001;
    
            // Don't need a camera if camera uniforms aren't required
            renderer.render({ scene: mesh });
        }
    }
  5. Perform basic arithmetic on vec3

    master

    The Vec3Func module provides several functions for basic arithmetic operations on 3D vectors (vec3). Most functions follow the pattern of taking an out vector as the first argument to store the result, allowing for memory reuse.

    Available arithmetic functions:

    • add(out, a, b): Adds vectors a and b.
    • subtract(out, a, b): Subtracts b from a.
    • multiply(out, a, b): Multiplies components of a and b.
    • divide(out, a, b): Divides components of a by b.
    • scale(out, a, b): Scales vector a by scalar b.
    • negate(out, a): Negates the components of a.
    • inverse(out, a): Returns the inverse of the components of a.
  6. Perform basic arithmetic on vec2

    master

    Use these functions to perform element-wise arithmetic operations on 2D vectors. Most functions require an out vector to store the result to avoid unnecessary allocations.

    Available operations:

    • add(out, a, b): Adds a and b.
    • subtract(out, a, b): Subtracts b from a.
    • multiply(out, a, b): Multiplies components of a and b.
    • divide(out, a, b): Divides components of a by b.
    • scale(out, a, b): Scales vector a by scalar b.
    • negate(out, a): Negates components of a.
    • inverse(out, a): Returns the inverse of components of a (1/x, 1/y).