Skip to content

Commit

Permalink
Check for NaN
Browse files Browse the repository at this point in the history
  • Loading branch information
rreusser committed Nov 19, 2021
1 parent 81bc016 commit 9c5e115
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 25 deletions.
4 changes: 2 additions & 2 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Instantiate a drawing command using the specified shaders.
- `vert` (string): vertex shader, using pragma specification defined below
- `frag` (string): fragment shader
- `debug`: Debug mode, which exposes additional properties for viewing triangle mesh
- `insertCaps` (boolean, default: `false`) Automatically insert a cap wherever a break is encountered, signaled by a position with `w = 0`. Allows drawing lines and caps with a single draw call. *Use this option with care.* If, for example, using miter joins and round caps, then *every segment instance* will have enough points to draw two full-resolution rounded caps, even if there are no breaks and the extra vertices never actually result in valid triangles.
- `insertCaps` (boolean, default: `false`) Automatically insert a cap wherever a break is encountered, signaled by a position with `w = 0` or first component `NaN`. Allows drawing lines and caps with a single draw call. *Use this option with care.* If, for example, using miter joins and round caps, then *every segment instance* will have enough points to draw two full-resolution rounded caps, even if there are no breaks and the extra vertices never actually result in valid triangles.

Additional configuration parameters are forwarded to a `regl` command which wraps drawing.

Expand All @@ -41,7 +41,7 @@ The vertex shader is parsed for GLSL `#pragma` directives which define data flow
- `attributeName`: name of attribute provided to draw command

### Vertex position *(required)*
A fixed property which defines computation of the `vec4` position of line vertices. Perspective division is performed automatically. Signal line breaks by returning a \`vec4` with `w = 0.0`. Unless using `insertCaps`, it is up to you to supply the corresponding endpoint data wherever this is a break.
A fixed property which defines computation of the `vec4` position of line vertices. Perspective division is performed automatically. Signal line breaks by returning a \`vec4` with `w = 0.0` or position.x `NaN`. Unless using `insertCaps`, it is up to you to supply the corresponding endpoint data wherever this is a break.
#### `#pragma lines: position = <functionName>(<attributeList>)`
- `functionName`: name of GLSL function which returns the `vec4`-valued position of the vertex
- `attributeList`: comma-separated list of vertex attribute names passed to the function
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 1.0.1

## Features

- Reenable NaN to signal line breaks. It seems to work now. [Confirm here](https://rreusser.github.io/regl-gpu-lines/docs/tests.html#miter/insert-caps/nan).

## 1.0.0

This release has no new features. Flipping the switch since, for the first time since starting, I don't have major new features or blocking bugs which would prevent me from calling this a piece of usable software. :tada:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Features:
- Compute positions and line width in the vertex shader
- Round joins, bevels, and miters (with miter limit)
- Square and rounded end caps
- Optional automatic end cap insertion, using `position.w == 0.0` to signal a line break (see: [docs/multiple.html](https://rreusser.github.io/regl-gpu-lines/docs/multiple.html))
- Optional automatic end cap insertion, using `position.w == 0.0` or alternatively `position.x` NaN to signal a line break (see: [docs/multiple.html](https://rreusser.github.io/regl-gpu-lines/docs/multiple.html))
- Regl-compatible attribute specification with strides and offsets
- Pass additional regl configuration to the constructor
- No dependencies; 11.6 KB minified, 4.7 KB gzipped.
Expand Down Expand Up @@ -54,7 +54,7 @@ See [API documentation](./API.md).

- [Basic example](https://rreusser.github.io/regl-gpu-lines/docs/basic.html): A minimal example. Just a line.
- [Variable width](https://rreusser.github.io/regl-gpu-lines/docs/variable-width.html): A basic line with variable width and color
- [Multiple lines](https://rreusser.github.io/regl-gpu-lines/docs/multiple.html): Use `position.w = 0` to break up lines into multiple segments
- [Multiple lines](https://rreusser.github.io/regl-gpu-lines/docs/multiple.html): Use position NaN to break up lines into multiple segments
- [Depth](https://rreusser.github.io/regl-gpu-lines/docs/depth.html): Layer lines using the z-coordinate
- [Closed loop](https://rreusser.github.io/regl-gpu-lines/docs/closed-loop.html): Create a closed loop by omitting end caps and repeating the first three vertices at the end.
- [Line border](https://rreusser.github.io/regl-gpu-lines/docs/border.html): Use `lineCoord` to draw a SDF line border
Expand Down
24 changes: 8 additions & 16 deletions examples/multiple.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@ const drawLines = reglLines(regl, {
precision highp float;
#pragma lines: attribute vec2 xy;
#pragma lines: attribute float break;
#pragma lines: position = getPosition(xy, break);
#pragma lines: position = getPosition(xy);
#pragma lines: width = getWidth();
#pragma lines: varying vec2 pos = getXY(xy);
// Return w = 0 wherever there's a break
vec4 getPosition(vec2 xy, float isBreak) {
if (isBreak > 0.0) return vec4(0);
vec4 getPosition(vec2 xy) {
return vec4(xy, 0, 1);
}
float getWidth() { return 40.0; }
Expand All @@ -31,6 +28,7 @@ const drawLines = reglLines(regl, {
// Turn off depth and turn on blending to make it very clear if we accidentally
// draw end caps twice
depth: { enable: false },
cull: {enable: true, face: 'back'},
blend: {
enable: true,
func: { srcRGB: "src alpha", srcAlpha: 1, dstRGB: "one minus src alpha", dstAlpha: 1 }
Expand All @@ -40,26 +38,21 @@ const drawLines = reglLines(regl, {
const n = 31;
const lineCount = 10;

// Detecting NaN in GLSL can be questionable, so we can just be verbose and use a separate
// attribute to indicate breaks.
const positions = [[0,0]];
const isBreak = [1];

function xy (line, i) {
let t = (i / (n - 1) * 2 - 1) * 0.9;
const y = ((line + 0.5) / lineCount * 2 - 1) * 0.9;
return [t, y + 1 / lineCount * Math.sin((t - line * 0.1) * 8.0)];
}

// Start with a break in order to signal a cap
const positions = [[NaN, NaN]];

for (let line = 0; line < lineCount; line++) {
for (let i = 0; i < n; i++) {
positions.push(xy(line, i));
isBreak.push(0);
}

// Add a dummy vertex and signal a break in the line
positions.push([0,0]);
isBreak.push(1);
// Signal a cap after each line
positions.push([NaN, NaN]);
}

// After this, render as normal!
Expand All @@ -69,7 +62,6 @@ const lineData = {
vertexCount: positions.length,
vertexAttributes: {
xy: regl.buffer(positions),
break: regl.buffer(new Uint8Array(isBreak))
},
};

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "regl-gpu-lines",
"version": "1.0.0",
"version": "1.0.1",
"description": "Pure GPU instanced, screen-projected lines for regl",
"main": "dist/regl-gpu-lines.min.js",
"repository": {
Expand Down
8 changes: 4 additions & 4 deletions src/draw-segment.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ ${debug ? 'varying float instanceID;' : ''}
${debug ? 'varying float vertexIndex;' : ''}
// This turns out not to work very well
// bool isnan(float val) {
// return (val < 0.0 || 0.0 < val || val == 0.0) ? false : true;
// }
bool isnan(float val) {
return (val < 0.0 || 0.0 < val || val == 0.0) ? false : true;
}
bool invalid(vec4 p) {
return p.w == 0.0;
return p.w == 0.0 || isnan(p.x);
}
void main() {
Expand Down
Binary file added test/fixtures/miter/insert-caps/nan/expected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions test/fixtures/miter/insert-caps/nan/fixture.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"width": 256,
"height": 128,
"command": {
"insertCaps": true,
"vert": [
"precision highp float;",
"#pragma lines: attribute vec2 xy",
"#pragma lines: position = getPosition(xy)",
"#pragma lines: width = getWidth()",
"float getWidth() { return 20.0; }",
"vec4 getPosition(vec2 xy) {",
" return vec4(xy, 0, 1);",
"}"
],
"frag": [
"precision lowp float;",
"void main () {",
" gl_FragColor = vec4(0,0,0,0.5);",
"}"
],
"blend": {
"enable": true,
"func": {
"srcRGB": "src alpha",
"srcAlpha": 1,
"dstRGB": "one minus src alpha",
"dstAlpha": 1
}
},
"depth": {
"enable": false
}
},
"vertexAttributes": {
"xy": [
[null, null],

[-0.8, 0.5],
[-0.3, 0.7],
[0.3, 0.5],
[0.8, 0.7],

[null, null],

[-0.8, -0.1],
[-0.3, 0.1],
[0.3, -0.1],
[0.8, 0.1],

[null, null],

[-0.8, -0.7],
[-0.3, -0.5],
[0.3, -0.7],
[0.8, -0.5],

[null, null]
]
},
"data": {
"join": "miter",
"cap": "round"
}
}

0 comments on commit 9c5e115

Please sign in to comment.