Blender Voronoi

Quick implementation of Blenders Voronoi Noise function in js.

by Morgan Gilroy

HTML

<BODY>
  <div class="panel">
    <form action="javascript:return(false);">

      <div class="inputContainer" id="deltax-container" name="deltax-container">
        <lable for="deltax">Delta x</lable>
        <div class="RangeBox">
          <input type="range" id="deltax" name="deltax" value="0">
          <input type="number" id="deltax-value" name="deltax-value" class="range-value">
        </div>
      </div>

      <div class="inputContainer" id="deltay-container" name="deltay-container">
        <lable for="deltay">Delta y</lable>
        <div class="RangeBox">
          <input type="range" id="deltay" name="deltay" value="0">
          <input type="number" id="deltay-value" name="deltay-value" class="range-value">
        </div>
      </div>

      <div class="inputContainer" id="deltaz-container" name="deltaz-container">
        <lable for="deltaz">Delta z</lable>
        <div class="RangeBox">
          <input type="range" id="deltaz" name="deltaz" value="0">
          <input type="number" id="deltaz-value" name="deltaz-value" class="range-value">
        </div>
      </div>

      <div class="inputContainer" id="mainNoiseScale-container" name="mainNoiseScale-container">
        <lable for="mainNoiseScale">Main Noise Scale</lable>
        <div class="RangeBox">
          <input type="range" id="mainNoiseScale" name="mainNoiseScale" value="0">
          <input type="number" id="mainNoiseScale-value" name="mainNoiseScale-value" class="range-value">
        </div>
      </div>

      <div class="inputContainer" id="mainFunction-container" name="mainFunction-container">
        <label for="mainFunction">Main Function</label>
        <select id="mainFunction" name="mainFunction">
        </select>
      </div>

      <div class="inputContainer toggle" id="subFunctionOne-container" name="subFunctionOne-container">
        <label for="subFunctionOne">Sub Function 1</label>
        <select id="subFunctionOne" name="subFunctionOne">
        </select>
     ...

CSS

html,
body {
  font-family: Verdana, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  background-color: #fafafa;
  background-image: radial-gradient(ellipse at center,rgba(235,235,235,.7) 0,rgba(200,200,200,.3) 50%,rgba(30,30,30,.25) 100%);
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

div {
  display: block;
}

div.panel {
  border-radius: 5px;
  border: 1px solid #AAAAAA;
  background-color: #f0f0f0;
  padding: 10px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}

form {
  display: block;
  margin-top: 0em;
}

button,
select {
  text-transform: none;
}

input,
select {
  width: 100%;
  margin: 2px 0;
  display: inline-block;
  border: 1px solid #ccc;
  box-shadow: inset 0 1px 3px #ddd, 0 0 10px 0px rgba(0, 0, 0, 0.05);
  border-radius: 4px;
  box-sizing: border-box;
  padding-left: 5px;
  padding-right: 5px;
  padding-top: 3px;
  padding-bottom: 3px;
}

input[type=checkbox] {
  width: 20px;
  height: 20px;
  position: relative;
}

input[type=checkbox] {
  padding: 18px;
}

input[type=checkbox]:checked:after {
  font-size: 28px;
  left: 6px;
}

input[type=range] {
  box-shadow: none;
}

input[type="range"]:before,
input[type="range"]:after {
  padding: 2px 5px 2px 5px;
  background-color: #f0f0f0;
  border: 1px solid #dbdbdb;
  border-radius: 4px;
  display: block;
  min-width: 30px;
  text-align: center;
  font-size: x-small;
  margin: auto;
}

input[type="range"]:before {
  content: attr(min) " ";
}

input[type="range"]:after {
  content: " " attr(max);
}

div.RangeBox {
  position: relative;
  width: 100%;
  display: flex;
}

div.RangeBox input[type=range] {
  margin-right: 10px;
}

div.RangeBox input[type=number] {
  width: 5em;
}

lable {
  display: block;
}

#texturePanel {
  display: inline-block;
  text-align: center;
}

canvas {
  border-radius: 3px;
  box-shadow: inset 0 1px 3px #ddd, 0 0 10px 0px rgba(0, 0, 0, 0.5);
  line-height: 0;
  vertical-align: bottom;
}

div.inputContainer {
  display:...

JavaScript

//var startTime = (new Date).getTime();
//var endTime = startTime + 5000;
var fpsList = [];
var fpsElement = document.getElementById("fps");

var settings = {
  width: 128,
  height: 128,
  canvasScale: 2,
  x: 0,
  y: 0,
  z: 0,

  deltax: 0,
  deltay: 0,
  deltaz: 0.1,
  mainNoiseScale: 20,
  normalize: true,
  e: 1,

  subNoiseScale: 1,
  octaves: 5,
  h: 1.5,
  lacunarity: 1.5,
  offset: 0.71,
  gain: 2,
  distortion: 1,
};

var limits = {
  deltax: {
    min: -2,
    max: 2,
    step: 0.1
  },
  deltay: {
    min: -2,
    max: 2,
    step: 0.1
  },
  deltaz: {
    min: -2,
    max: 2,
    step: 0.1
  },
  mainNoiseScale: {
    min: 1,
    max: 100,
    step: 1
  },
  subNoiseScale: {
    min: 0,
    max: 2,
    step: 0.1
  },
  octaves: {
    min: 0,
    max: 8,
    step: 1
  },
  h: {
    min: 0,
    max: 5,
    step: 0.1
  },
  e: {
    min: 0.1,
    max: 5,
    step: 0.1
  },
  lacunarity: {
    min: 0.1,
    max: 5,
    step: 0.1
  },
  offset: {
    min: -2,
    max: 2,
    step: 0.1
  },
  gain: {
    min: 0,
    max: 5,
    step: 0.1
  },
  distortion: {
    min: -2,
    max: 2,
    step: 0.1
  },
};

var avalableOptions = ['subFunctionOne', 'subFunctionTwo', 'subNoiseScale', 'hard', 'octaves', 'h', 'lacunarity', 'offset', 'gain', 'distortion'];

var mainFunctions = {};

mainFunctions['Single'] = {
  options: ['subFunctionOne'],
  f: function(x, y, z) {
    return settings.subFunctionOne(x, y, z);
  }
};

mainFunctions['BLI_gNoise'] = {
  options: ['subFunctionOne', 'subNoiseScale', 'hard'],
  f: function(x, y, z) {
    return noise.BLI_gNoise(settings.subNoiseScale, x, y, z, settings.hard, settings.subFunctionOne);
  }
};

mainFunctions['BLI_gTurbulence'] = {
  options: ['subFunctionOne', 'subNoiseScale', 'hard', 'octaves'],
  f: function(x, y, z) {
    return noise.BLI_gTurbulence(settings.subNoiseScale, x, y, z, settings.octaves, settings.hard, settings.subFunctionOne);
  }
};

mainFunctions['mg_fBm'] = {
  options: ['subFunctionOne', 'lacunarity',...