2

I am currently doing some 3d modeling using babylonjs. I need to create a pressure map from given pressure at specific points. I am doing that using IDW. However this means that even with my map being a size of 70x90 grid requires me to have an array of 25200 (4 rgba values for each pixel) entries. Then this buffer is passed to a RawTexture for assigning it to a material, that is overlaid on the object

I am using a web worker, because I have to update the pressure values every 100ms and I don't want to block the main thread.The issue occurs when I am return that array (created in calculate function) from a service worker.

For some reason the memory usage just keeps going up, without stopping. It eventually goes up to around 1.5 gigabytes and I have to kill it.

The question : Is there any way to prevent this and what could be causing such high memory usage?

Worker:

// @flow
import { find, propEq, both } from 'ramda';
import { colorFromValue } from './color';
import { inverseDistance, distanceValues } from './math';

const findPoint = (x: number, y: number) =>
  find(both(propEq('x', x), propEq('y', y)));

const distanceDict = {};

/* eslint-disable */
function calculate(options: Object, pList: Array<*>) {
  const points = pList || [];
  const { height, width } = options;
  const gridWidth = width * 4;
  const grid = new Uint8Array(options.width * options.height * 4);

  for (let y = 0; y < height; y += 1) {
    const rW = y * gridWidth;
    for (let i = 0; i < gridWidth; i += 4) {
      const index = i + rW;
      const x = i / 4;
      const dictKey = `${x}--${y}`;
      let bottoms = distanceDict[dictKey];

      if (bottoms === undefined) {
        bottoms = distanceValues(points, x, y);
        distanceDict[dictKey] = bottoms;
      }
      const point = findPoint(x, y)(points);

      const value = point !== undefined && point !== null ?
        point.value : inverseDistance(points, bottoms);
      const color = colorFromValue(value);
      grid[index] = color[0];
      grid[index + 1] = color[1];
      grid[index + 2] = color[2];
      grid[index + 3] = 255;
    }
  }
  return grid;
}

self.onmessage = (e) => {
  const { points, options } = e.data;
  const grid = calculate(options, points);
  self.postMessage(grid.buffer, [grid.buffer]);
};

Painting:

modifyNodes = (points: Array<*>) => new Promise((res, rej) => {
  this.worker.onmessage = (e) => {
    this._texture.update(new Uint8Array(e.data));
    res();
  } 
  const data = {
    options: this._options,
    points,
  };
  this.worker.postMessage(data);
})
August
  • 1,722
  • 5
  • 20
  • 37

1 Answers1

2

So it seems the issue was in the colorFromValue function that was memoized. Because the values had quite few decimal points it could create up to 9! new entries into cache, so it drove up the memory usage...

August
  • 1,722
  • 5
  • 20
  • 37