Bump mapping heightmap

by Gwyn Milcote

HTML

Size: <select id='select_size'>
    <option>16</option>
    <option>32</option>
    <option selected>64</option>
    <option>128</option>
    <option>256</option>
</select>
Roughness: <input type='number' id='select_roughness' min='1' max='20' value='5'> 
Tile pixels: <input type='number' id='select_tileSize' min='1' max='10' value='3'> 
Colours: <input type='number' id='select_colours' min='2' max='15' value='15'>
 <button id='generate_btn'>New map</button><br>

<div id='canvas_container'>
    <canvas id="output_canvas"></canvas>
</div>
<br><textarea id='output_data'></textarea>

CSS

#canvas_container {
    margin: 20px 0;
    text-align: center;
}

input {
    width: 50px;
}

#output_data {
    width: 100%;
    min-height: 150px;
}

JavaScript

const hex = ["f6f5f5", "ccc7c5", "A0A69F", "777d76", "466a3f", "578546", "83A64B", "a8c977", "CDDBAB", "F2EEC9", "93D8ED", "61C2E0", "26A5CC", "0D8CB3", "055EA6"];

class QuickTerrain {
    
    constructor(){
        this.generateMap();
    }
    
    emptyMap(){
        this.map = [];
        for(let x = 0; x < this.size + 1; x++){
            for(let y = 0; y < this.size + 1; y++){
                this.map[x] = [];
            }
        }
    }
    
    generateMap(){
        let vars = ["size", "roughness", "colours", "tileSize"];
        for(let v of vars){
            let input = document.getElementById("select_" + v);
            this[v] = Number(input.value);
        }
        this.emptyMap();
        this.startDisplacement();
    }

    drawMap(){
        let canvas = document.getElementById("output_canvas"),
            ctx = canvas.getContext("2d");
        canvas.width = this.size * this.tileSize;
        canvas.height = canvas.width;
        
        // Certain palettes for clearer viewing.
        let palette = [],
            finalMap = [];
        let palettes = [
            [7,11],
            [4,7,11],
            [4,7,11,13],
            [4,7,9,12,13],
            [2,4,5,7,11,13],
            [2,4,7,8,10,12,13],
            [1,3,4,7,8,10,12,13],
            [1,3,4,7,8,10,12,13,14],
            [1,3,4,6,7,8,10,12,13,14],
            [1,3,4,5,6,7,8,10,12,13,14],
            [1,2,3,4,5,6,7,8,10,12,13,14],
            [1,2,3,4,5,6,7,8,10,11,12,13,14],
            [1,2,3,4,5,6,7,8,9,10,11,12,13,14],
            [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
        ];
        let indexes = palettes[this.colours - 2];
        for(let i of indexes){
            palette.push(hex[i - 1]);
        }
        
        for(let x = 0; x <= this.size; x++){
            let row = [];
            for(let y = 0; y <= this.size; y++){
      
                let altitude = Math.round(this.map[x][y] * (this.colours - 1));
                row.push(altitude);
               ...