From 8948c1df067dbbaa4775e70889666d13cb73c311 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sun, 6 Aug 2017 15:47:12 +0000 Subject: [PATCH] LUT visualizer --- docs/lut.html | 33 ++++++++++ docs/lut.js | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 docs/lut.html create mode 100644 docs/lut.js diff --git a/docs/lut.html b/docs/lut.html new file mode 100644 index 0000000..b9d12ad --- /dev/null +++ b/docs/lut.html @@ -0,0 +1,33 @@ + + + + LUT experiment + + + + +
+ + + + + diff --git a/docs/lut.js b/docs/lut.js new file mode 100644 index 0000000..ab999fe --- /dev/null +++ b/docs/lut.js @@ -0,0 +1,176 @@ +'use strict'; + +function leftPad(str, len) { + while (str.length < len) { + str = '0' + str; + } + return str; +} + +function createElement(parentNode, tagName, opt_text) { + let element = document.createElement(tagName); + if (opt_text !== undefined) { + element.textContent = opt_text; + } + parentNode.appendChild(element); + return element; +} + + +class Point { + constructor(r, g, b) { + this.r = r; + this.g = g; + this.b = b; + + this.HEX_DIV = 256; + this.HEX_PAD = 2; + } + + getHexColor() { + return '#' + this.toHexValue(this.r) + this.toHexValue(this.g) + this.toHexValue(this.b); + } + + toHexValue(val) { + return leftPad(Math.floor(val / this.HEX_DIV).toString(16), this.HEX_PAD); + } + + addSwatch(parentElement) { + let elem = createElement(parentElement, 'td') + elem.style = 'width: 5em; text-align: center; text-shadow: 1px 1px 0 white; background-color: ' + this.getHexColor(); + return elem; + } + + addColorCells(parentElement) { + this.addSwatch(parentElement); + createElement(parentElement, 'td', leftPad(this.r.toString(16), 4)); + createElement(parentElement, 'td', leftPad(this.g.toString(16), 4)); + createElement(parentElement, 'td', leftPad(this.b.toString(16), 4)); + } +} + +class LutExperiment { + constructor(container) { + this.container = container; + + this.SIZE = 5; + this.NUM_COLOR = 2 ** 16; + this.PER_BLOCK = Math.floor(this.NUM_COLOR / (this.SIZE - 1)); + + this.generatePoints(); + + this.colorChecker = [ + new Point(0x7300, 0x5200, 0x4400), + new Point(0xc200, 0x9600, 0x8200), + new Point(0x6200, 0x7a00, 0x9d00), + new Point(0x5700, 0x6c00, 0x4300), + new Point(0x8500, 0x8000, 0xb100), + new Point(0x6700, 0xbd00, 0xaa00), + new Point(0xd600, 0x7e00, 0x2c00), + new Point(0x5000, 0x5b00, 0xa600), + new Point(0xc100, 0x5a00, 0x6300), + new Point(0x5e00, 0x3c00, 0x6c00), + new Point(0x9d00, 0xbc00, 0x4000), + new Point(0xe000, 0xa300, 0x2e00), + new Point(0x3800, 0x3d00, 0x9600), + new Point(0x4600, 0x9400, 0x4900), + new Point(0xaf00, 0x3600, 0x3c00), + new Point(0xe700, 0xc700, 0x1f00), + new Point(0xbb00, 0x5600, 0x9500), + new Point(0x0800, 0x8500, 0xa100), + new Point(0xf300, 0xf300, 0xf200), + new Point(0xc800, 0xc800, 0xc800), + new Point(0xa000, 0xa000, 0xa000), + new Point(0x7a00, 0x7a00, 0x7900), + new Point(0x5500, 0x5500, 0x5500), + new Point(0x3400, 0x3400, 0x3400), + ]; + + this.showColorChecker(); + this.showResults(); + } + + generatePoints() { + this.points = new Array(); + for (let x = 0; x < this.SIZE; ++x) { + this.points[x] = new Array(); + + for (let y = 0; y < this.SIZE; ++y) { + this.points[x][y] = new Array(); + + for (let z = 0; z < this.SIZE; ++z) { + this.points[x][y][z] = new Point(this.getColorValue(x), this.getColorValue(y), this.getColorValue(z)); + } + } + } + } + + getColorValue(index) { + return Math.min(this.NUM_COLOR - 1, this.PER_BLOCK * index); + } + + showColorChecker() { + let table = createElement(this.container, 'table'); + + let headers = createElement(table, 'tr'); + createElement(headers, 'th', 'Swatch'); + createElement(headers, 'th', 'R'); + createElement(headers, 'th', 'G'); + createElement(headers, 'th', 'B'); + createElement(headers, 'th', 'Root'); + createElement(headers, 'th', 'x+1'); + createElement(headers, 'th', 'y+1'); + createElement(headers, 'th', 'z+1'); + createElement(headers, 'th', 'x+1,y+1'); + createElement(headers, 'th', 'x+1,z+1'); + createElement(headers, 'th', 'y+1,z+1'); + + for (let point of this.colorChecker) { + let tr = createElement(table, 'tr'); + point.addColorCells(tr); + + let rootX = Math.min(Math.floor(point.r / this.PER_BLOCK), this.SIZE - 2); + let rootY = Math.min(Math.floor(point.g / this.PER_BLOCK), this.SIZE - 2); + let rootZ = Math.min(Math.floor(point.b / this.PER_BLOCK), this.SIZE - 2); + + this.points[rootX][rootY][rootZ].addSwatch(tr).textContent = rootX + ',' + rootY + ',' + rootZ; + this.points[rootX + 1][rootY][rootZ].addSwatch(tr); + this.points[rootX][rootY + 1][rootZ].addSwatch(tr); + this.points[rootX][rootY][rootZ + 1].addSwatch(tr); + this.points[rootX + 1][rootY + 1][rootZ].addSwatch(tr); + this.points[rootX + 1][rootY][rootZ + 1].addSwatch(tr); + this.points[rootX][rootY + 1][rootZ + 1].addSwatch(tr); + } + } + + showResults() { + let table = createElement(this.container, 'table'); + + let headers = createElement(table, 'tr'); + createElement(headers, 'th', 'X'); + createElement(headers, 'th', 'Y'); + createElement(headers, 'th', 'Z'); + createElement(headers, 'th', 'Swatch'); + createElement(headers, 'th', 'R'); + createElement(headers, 'th', 'G'); + createElement(headers, 'th', 'B'); + + for (let x = 0; x < this.SIZE; ++x) { + let square = this.points[x]; + + for (let y = 0; y < this.SIZE; ++y) { + let row = square[y]; + + for (let z = 0; z < this.SIZE; ++z) { + let point = row[z]; + + let tr = createElement(table, 'tr'); + createElement(tr, 'td', x); + createElement(tr, 'td', y); + createElement(tr, 'td', z); + point.addColorCells(tr); + } + } + } + } +}