Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request: contour/contour-fill from ZARR? #74

Open
keltonhalbert opened this issue Jun 6, 2022 · 0 comments
Open

Request: contour/contour-fill from ZARR? #74

keltonhalbert opened this issue Jun 6, 2022 · 0 comments
Assignees

Comments

@keltonhalbert
Copy link

This seems like something that could be a good pull request opportunity, but I don't have much experience with vertex/fragment shaders or WebGL. So, if this question is outside of the scope of the project, feel free to say so. But I think it would be interesting if the vertex/fragment shaders could be used to perform contour and contour-fill plots on the map. I know that the simplest thing would be to generate contours as geojsons or generate some pbf tiles, but that requires an additional preprocessing step. Theoretically, the Zarr data is all available to the shaders and therefore can be contoured.

I found some some leads about line drawing shaders from here: https://mattdesl.svbtle.com/drawing-lines-is-hard
with a copy of the vertex shader below.

What would be required to add a contour option to 'grid', 'dotgrid', and 'texture'? I see in the documentation custom shaders are supported, but I'm not exactly clear on the process of adding one. I'd be willing to contribute any progress in a pull request, but I don't quite know where to start. Just have some ideas. Is there a process or method I should follow when looking to add a new visualization method to this library? Tips, ideas, pointers, etc all welcome.

// The MIT License (MIT) Copyright (c) 2015 Matt DesLauriers
const vert = `
uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;
uniform float aspect;
uniform float thickness;
uniform int miter;
attribute vec3 prevPosition;
attribute vec3 currPosition;
attribute vec3 nextPosition;
attribute float offsetScale;
void main() {
  vec2 aspectVec = vec2(aspect, 1.0);
  mat4 projViewModel = projection * view * model;
  vec4 prevProjected = projViewModel * vec4(prevPosition, 1.0);
  vec4 currProjected = projViewModel * vec4(currPosition, 1.0);
  vec4 nextProjected = projViewModel * vec4(nextPosition, 1.0);
  // get 2D screen space with W divide and aspect correction
  vec2 prevScreen = prevProjected.xy / prevProjected.w * aspectVec;
  vec2 currScreen = currProjected.xy / currProjected.w * aspectVec;
  vec2 nextScreen = nextProjected.xy / nextProjected.w * aspectVec;
  float len = thickness;
  // starting point uses (next - current)
  vec2 dir = vec2(0.0);
  if (currScreen == prevScreen) {
    dir = normalize(nextScreen - currScreen);
  }
  // ending point uses (current - previous)
  else if (currScreen == nextScreen) {
    dir = normalize(currScreen - prevScreen);
  }
  // somewhere in middle, needs a join
  else {
    // get directions from (C - B) and (B - A)
    vec2 dirA = normalize((currScreen - prevScreen));
    if (miter == 1) {
      vec2 dirB = normalize((nextScreen - currScreen));
      // now compute the miter join normal and length
      vec2 tangent = normalize(dirA + dirB);
      vec2 perp = vec2(-dirA.y, dirA.x);
      vec2 miter = vec2(-tangent.y, tangent.x);
      dir = tangent;
      len = thickness / dot(miter, perp);
    } else {
      dir = dirA;
    }
  }
  vec2 normal = vec2(-dir.y, dir.x) * thickness;
  normal.x /= aspect;
  vec4 offset = vec4(normal * offsetScale, 0.0, 1.0);
  gl_Position = currProjected + offset;
}`

const frag = `
precision mediump float;
uniform vec4 color;
void main() {
  gl_FragColor = color;
}`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants