대량의 점의 2차원 그림

15280 단어 WebGLJavaScriptregl
안녕하세요.
대량점의 2차원도와 관련해 이용regl(WebGL 라이브러리)의 고속성regl을 시도한 목적은 웹GL을 간단하게 기술하기 위한 것이다.mousedown,mouseeup,wheel,resize 활동에 대한 처리는 스스로 진행했습니다.
1000만 점(ten milions)1을 그려도 초점이 바뀔 때 그림 응답이 좋다.
scatter.jpg
scatter.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8>
    <style>
    html,body{
        height: 100%;
        margin: 0;
    }
    .canvas{
        height: 100%;
        padding: 0px;
    }
    </style>
  </head>
  <body>
    <div class="canvas"></div>
  </body>
  <script language="javascript" src="https://npmcdn.com/regl/dist/regl.min.js"></script>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <script language="javascript">
  const pointSize = 8;
  const nPoints =   100000;
  const timerDelay = 100;
  const deltaY = 100;

  const rng = d3.randomNormal(0, 0.3);
  const points = d3.range(nPoints).map(() => 
     ({ x: rng(),
        y: rng(),
        color: [Math.random(), Math.random(), 0]})
  );

  let scale = 1, offset = [0, 0];
  let timer, dragStart;

  const mouseDown = e => {
    dragStart = {x: e.pageX, y: e.pageY};
  }

  const mouseUp = e => {
    offset[0] += (e.pageX - dragStart.x) * 2 / window.innerWidth;
    offset[1] += (e.pageY - dragStart.y) * 2 / window.innerHeight;
    draw();
  }

  const wheelScroll = e => {
    const magnification = Math.exp(-e.deltaY / deltaY);
    scale *= magnification;
    offset[0] *= magnification;
    offset[1] *= magnification;
    draw();
  }

  const resize = e => {
    if (timer !== false) {
      clearTimeout(timer);
    }
    timer = setTimeout(function () {
      regl.poll();
      draw();
    }, timerDelay);
  };

  document.addEventListener("mousedown", mouseDown, false);
  document.addEventListener("mouseup", mouseUp, false);
  document.addEventListener("wheel", wheelScroll);
  window.addEventListener('resize', resize);

const frag = `
  precision highp float;
  varying vec3 fragColor;
  void main() {
    gl_FragColor = vec4(fragColor, 1);
  }`;

const vert = `
  varying vec3 fragColor;
  attribute vec2 pos;
  attribute vec3 color;
  uniform float pointSize;
  uniform float scale;
  uniform vec2 offset;

  vec2 normalizeCoords(vec2 pos) {
    float x = pos[0] * scale + offset[0];
    float y = pos[1] * scale + offset[1];
    return vec2(x, -y);
  }

  void main() {
    fragColor = color;
    gl_PointSize = pointSize;
    gl_Position = vec4(normalizeCoords(pos), 0, 1);
  }`;


  const draw = () => {
    drawPoints({scale: scale, offset: offset});
  }

  const regl = createREGL({
    container: document.querySelector('.canvas'),
  });

  const drawPoints = regl({
    frag: frag,
    vert: vert,
    primitive: 'points',
    count: points.length,
    attributes: {
      pos: points.map(d => [d.x, d.y]),
      color: points.map(d => d.color)
    },
    uniforms: {
      pointSize: pointSize,
      scale: regl.prop('scale'),
      offset: regl.prop('offset'),
    }
  });

  draw();
  </script>
</html>
그런데 1억 점을 그리려면 배열 관리 상한선을 넘은 것 같아 이상이 생겼다. 

좋은 웹페이지 즐겨찾기