Git Product home page Git Product logo

regl-gpu-lines's Introduction

Lines with round joins and caps

regl-gpu-lines

Pure GPU, instanced, screen-projected lines for regl

API documentation →

Live example →

All examples →

This module implements a very general command for drawing lines using the regl WebGL library.

Architecturally this module has two goals:

  • Data may live on the GPU.
  • Minimize unnecessary constraints.

To accomplish this, it implements a simple pragma-based interface for specifying how your attributes connect to line properties and to varyings.

Features:

  • Configure your own attributes, varyings, uniforms, and shaders
  • Compute position and line width in the vertex shader
  • GPU computation of round joins, bevels, and miters (with miter limit), and square and rounded end caps.
  • Optional end cap insertion, using position.w == 0.0 or alternatively position.x NaN to signal a line break (see: docs/multiple.html)
  • Regl-compatible attribute specification with strides and offsets
  • Forward additional regl configuration to the draw command
  • Seamlessly permits substitution of Vertex Array Objects (VAOs)
  • 13.4 KB minified, 5.3 KB gzipped. No dependencies (although it is expected to be used together with regl, which requirement I'd like to consider removing)

Limitations:

  • ANGLE_instanced_arrays extension is required (which ought to be universally supported)
  • Width is best varied slowly as line joins to not take into account varying width
  • Automatic end cap insertion wastes vertices when the cap resolution exceeds the join resolution
  • Line dashes are not built-in, but you can easily build them yourself

Install

The dist/ directory contains UMD bundles, or you may use from a CDN, e.g. https://unpkg.com/regl-gpu-lines@latest. Both expose the module as reglLines.

Otherwise install from npm:

npm install regl-gpu-lines

API

See API documentation.

Examples

  • Basic example: A minimal example. Just a line.
  • Variable width: A basic line with variable width and color
  • Multiple lines: Use position NaN to break up lines into multiple segments
  • Depth: Layer lines using the z-coordinate
  • Closed loop: Create a closed loop by omitting end caps and repeating the first three vertices at the end.
  • Line border: Use lineCoord to draw a SDF line border
  • Interleaved attributes: Instead of a regl buffer, you can pass a regl-style attribute description with buffer, stride, offset, and divisor properties in order to used interleaved, packed attribute data.
  • Torus knot: A torus knot with layering which can be difficult to draw with SVG.
  • Batched rendering: Illustrates how to take advantage of reorder: true to reduce shader program changes from, in this example, thirty to four.
  • Post-projection: Illustrates post-project to draw lines projected onto a plane from some other angle.
  • Vertex Array Object (VAO): Illustrates seamless swapping of VAO for vertex and endpoint attributes.
  • Fake instancing: Sort of allows you to mimic instanced rendering on top of instanced rendering, albeit with some duplication of data.
  • Debug page: Shows how to use instanceID and triStripCoord varyings to draw a wireframe
  • Full debug view: A page for exploring all the bells and whistles
  • GPGPU Strange Attractors: Feed a GPU particle simulation from texture data directly into line rendering

GPGPU Lorenz Attractor

A minimal example looks like the following, where a vec2 attribute xy is connected to line position via a GLSL #pragma.

const drawLines = reglLines(regl, {
  vert: `
    precision highp float;

    #pragma lines: attribute vec2 xy;
    #pragma lines: position = getPosition(xy);
    vec4 getPosition(vec2 xy) { return vec4(xy, 0, 1); }

    #pragma lines: width = getWidth();
    uniform float width;
    float getWidth() { return width; }`,
  frag: `
    precision lowp float;
    void main () {
      gl_FragColor = vec4(1);
    }`,
  uniforms: {
    width: (ctx, props) => props.customWidth * ctx.pixelRatio
  }
});

const xy = [[-1, 1], [-0.5, -1], [0, 1], [0.5, -1], [1, 1]];
const lineData = {
  customWidth: 20,
  join: 'round',
  cap: 'round',
  vertexCount: xy.length,
  vertexAttributes: {
    xy: regl.buffer(xy)
  },
  endpointCount: 2,
  endpointAttributes: {
    xy: regl.buffer([xy.slice(0, 3), xy.slice(-3).reverse()])
  }
};

drawLines(lineData);

Development

Examples

Serve example pages—e.g. the example in examples/closed-loop.js—with

npm start closed-loop

Tests

Run live-reloading render tests with

npm run serve-render-tests

Executing the render tests from the CLI requires the headless-gl module. You may use nodemon to live-run the render tests when the code is changed.

npm install -g nodemon
nodemon test/render.js

Filter tests with

FILTER=miter/basic nodemon test/render.js

and update expectation images with

UPDATE=1 FILTER=miter/basic node test/render.js

You may view the tests, run against the latest version from unpkg.com, at https://rreusser.github.io/regl-gpu-lines/docs/tests.html

See also

License

© 2021 Ricky Reusser. MIT License.

regl-gpu-lines's People

Contributors

rreusser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

regl-gpu-lines's Issues

CPU-Side, Alternative Equivalent?

This is more of a discussion than a suggestion for the library, but in general, I love how this library has variable-width strokes and colors, which are great for working with a stylus.
However, my particular use case really needs a CPU-side solution, and in C / C++ no less.
Somehow I have been unable to find a library that supports the above and I'm wondering if you could offer suggestions for where to find something like that, or references for how to build it or adapt it from existing solutions. In short, it's strange, but variable-width and color per-vertex polycurves seem very rare.

Degenerate triangle show up on some devices

In version 1.0.0, iOS 15 Safari shows some overlapping pixels where caps meet segments. I'm not sure what's causing this, unless maybe triangle strips require knowledge that it's a triangle strip in order to avoid? I thought as long as the tris met floating-point-correctly that the GPU had some magic way to get this right.

At any rate it's not a blocker and there are bigger self-intersection issues with transparent lines anyway, but it'd be nice to understand.

346edbe281ea15d0dda9eebd9e4658591282bdb192576e0825513c3dd6f9a101

error on npm install after cloning repo

i cloned this repo & did npm install (was hoping to try out some of the examples). got this error:

marina@pumpkin:~/dev/regl-gpu-lines$ npm install
npm ERR! code 1
npm ERR! path /home/marina/dev/regl-gpu-lines/node_modules/gl
npm ERR! command failed
npm ERR! command sh -c prebuild-install || node-gyp rebuild
npm ERR! (node:13786) [DEP0150] DeprecationWarning: Setting process.config is deprecated. In the future the property will be read-only.
npm ERR! (Use `node --trace-deprecation ...` to show where the warning was created)
npm ERR! Package xi was not found in the pkg-config search path.
npm ERR! Perhaps you should add the directory containing `xi.pc'
npm ERR! to the PKG_CONFIG_PATH environment variable
npm ERR! No package 'xi' found
npm ERR! gyp: Call to 'pkg-config --libs-only-L --libs-only-other x11 xi xext' returned exit status 1 while in angle/src/angle.gyp. while loading dependencies of binding.gyp while trying to load binding.gyp
npm ERR! gyp ERR! configure error 
npm ERR! gyp ERR! stack Error: `gyp` failed with exit code: 1
npm ERR! gyp ERR! stack     at ChildProcess.onCpExit (/home/marina/dev/regl-gpu-lines/node_modules/node-gyp/lib/configure.js:351:16)
npm ERR! gyp ERR! stack     at ChildProcess.emit (node:events:365:28)
npm ERR! gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
npm ERR! gyp ERR! System Linux 5.4.0-90-generic
npm ERR! gyp ERR! command "/usr/local/bin/node" "/home/marina/dev/regl-gpu-lines/node_modules/.bin/node-gyp" "rebuild"
npm ERR! gyp ERR! cwd /home/marina/dev/regl-gpu-lines/node_modules/gl
npm ERR! gyp ERR! node -v v16.1.0
npm ERR! gyp ERR! node-gyp -v v7.1.2
npm ERR! gyp ERR! not ok

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/marina/.npm/_logs/2021-11-16T22_39_07_600Z-debug.log

my node version is 16.1.0 and my npm version is 7.12.1

any idea what might be going on?

Remove dependence on regl

I'd love for regl to be an afterthought and refactor the core of this module not to actually depend on it. I don't quite know what it means though to write a raw WebGL 1/2 module which uses advanced features but doesn't require an agonizing amount of very specialized interfacing in order to use. Vlad's WebGL 2 boilerplate is certainly very interesting as a potential approach, though until it grows to encompass all of the underlying API surface area, it sort of feels like an all-or-none buy in; you either have to go all the way down to the level of individual WebGL API calls or all the way up to the level of a library which entirely wraps it (threejs, regl). Unless a lightweight wrapper would allow you to just make the raw WebGL calls yourself, which may be the case.

Add vertex post-processing function

Sometimes it's necessary to, for example, draw lines on a flat surface and then project those into three dimensions after line vertex computation. It seems necessary to add a post-processing pragma for the vertex shader. This is easy to implement but just want to think it over before adding.

Publish to npm

It's a couple versions behind. Gotta dig up those credentials, then will be able to publish.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.