UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

221 lines (210 loc) 8.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.reinhardToneMapping = exports.neutralToneMapping = exports.linearToneMapping = exports.cineonToneMapping = exports.agxToneMapping = exports.acesFilmicToneMapping = void 0; var _TSLBase = require("../tsl/TSLBase.js"); var _ConditionalNode = require("../math/ConditionalNode.js"); var _MathNode = require("../math/MathNode.js"); var _OperatorNode = require("../math/OperatorNode.js"); /** * Linear tone mapping, exposure only. * * @tsl * @function * @param {Node<vec3>} color - The color that should be tone mapped. * @param {Node<float>} exposure - The exposure. * @return {Node<vec3>} The tone mapped color. */ const linearToneMapping = exports.linearToneMapping = /*@__PURE__*/(0, _TSLBase.Fn)(([color, exposure]) => { return color.mul(exposure).clamp(); }).setLayout({ name: 'linearToneMapping', type: 'vec3', inputs: [{ name: 'color', type: 'vec3' }, { name: 'exposure', type: 'float' }] }); /** * Reinhard tone mapping. * * Reference: {@link https://www.cs.utah.edu/docs/techreports/2002/pdf/UUCS-02-001.pdf} * * @tsl * @function * @param {Node<vec3>} color - The color that should be tone mapped. * @param {Node<float>} exposure - The exposure. * @return {Node<vec3>} The tone mapped color. */ const reinhardToneMapping = exports.reinhardToneMapping = /*@__PURE__*/(0, _TSLBase.Fn)(([color, exposure]) => { color = color.mul(exposure); return color.div(color.add(1.0)).clamp(); }).setLayout({ name: 'reinhardToneMapping', type: 'vec3', inputs: [{ name: 'color', type: 'vec3' }, { name: 'exposure', type: 'float' }] }); /** * Cineon tone mapping. * * Reference: {@link http://filmicworlds.com/blog/filmic-tonemapping-operators/} * * @tsl * @function * @param {Node<vec3>} color - The color that should be tone mapped. * @param {Node<float>} exposure - The exposure. * @return {Node<vec3>} The tone mapped color. */ const cineonToneMapping = exports.cineonToneMapping = /*@__PURE__*/(0, _TSLBase.Fn)(([color, exposure]) => { // filmic operator by Jim Hejl and Richard Burgess-Dawson color = color.mul(exposure); color = color.sub(0.004).max(0.0); const a = color.mul(color.mul(6.2).add(0.5)); const b = color.mul(color.mul(6.2).add(1.7)).add(0.06); return a.div(b).pow(2.2); }).setLayout({ name: 'cineonToneMapping', type: 'vec3', inputs: [{ name: 'color', type: 'vec3' }, { name: 'exposure', type: 'float' }] }); // source: https://github.com/selfshadow/ltc_code/blob/master/webgl/shaders/ltc/ltc_blit.fs const RRTAndODTFit = /*@__PURE__*/(0, _TSLBase.Fn)(([color]) => { const a = color.mul(color.add(0.0245786)).sub(0.000090537); const b = color.mul(color.add(0.4329510).mul(0.983729)).add(0.238081); return a.div(b); }); /** * ACESFilmic tone mapping. * * Reference: {@link https://github.com/selfshadow/ltc_code/blob/master/webgl/shaders/ltc/ltc_blit.fs} * * @tsl * @function * @param {Node<vec3>} color - The color that should be tone mapped. * @param {Node<float>} exposure - The exposure. * @return {Node<vec3>} The tone mapped color. */ const acesFilmicToneMapping = exports.acesFilmicToneMapping = /*@__PURE__*/(0, _TSLBase.Fn)(([color, exposure]) => { // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT const ACESInputMat = (0, _TSLBase.mat3)(0.59719, 0.35458, 0.04823, 0.07600, 0.90834, 0.01566, 0.02840, 0.13383, 0.83777); // ODT_SAT => XYZ => D60_2_D65 => sRGB const ACESOutputMat = (0, _TSLBase.mat3)(1.60475, -0.53108, -0.07367, -0.10208, 1.10813, -0.00605, -0.00327, -0.07276, 1.07602); color = color.mul(exposure).div(0.6); color = ACESInputMat.mul(color); // Apply RRT and ODT color = RRTAndODTFit(color); color = ACESOutputMat.mul(color); // Clamp to [0, 1] return color.clamp(); }).setLayout({ name: 'acesFilmicToneMapping', type: 'vec3', inputs: [{ name: 'color', type: 'vec3' }, { name: 'exposure', type: 'float' }] }); const LINEAR_REC2020_TO_LINEAR_SRGB = /*@__PURE__*/(0, _TSLBase.mat3)((0, _TSLBase.vec3)(1.6605, -0.1246, -0.0182), (0, _TSLBase.vec3)(-0.5876, 1.1329, -0.1006), (0, _TSLBase.vec3)(-0.0728, -0.0083, 1.1187)); const LINEAR_SRGB_TO_LINEAR_REC2020 = /*@__PURE__*/(0, _TSLBase.mat3)((0, _TSLBase.vec3)(0.6274, 0.0691, 0.0164), (0, _TSLBase.vec3)(0.3293, 0.9195, 0.0880), (0, _TSLBase.vec3)(0.0433, 0.0113, 0.8956)); const agxDefaultContrastApprox = /*@__PURE__*/(0, _TSLBase.Fn)(([x_immutable]) => { const x = (0, _TSLBase.vec3)(x_immutable).toVar(); const x2 = (0, _TSLBase.vec3)(x.mul(x)).toVar(); const x4 = (0, _TSLBase.vec3)(x2.mul(x2)).toVar(); return (0, _TSLBase.float)(15.5).mul(x4.mul(x2)).sub((0, _OperatorNode.mul)(40.14, x4.mul(x))).add((0, _OperatorNode.mul)(31.96, x4).sub((0, _OperatorNode.mul)(6.868, x2.mul(x))).add((0, _OperatorNode.mul)(0.4298, x2).add((0, _OperatorNode.mul)(0.1191, x).sub(0.00232)))); }); /** * AgX tone mapping. * * @tsl * @function * @param {Node<vec3>} color - The color that should be tone mapped. * @param {Node<float>} exposure - The exposure. * @return {Node<vec3>} The tone mapped color. */ const agxToneMapping = exports.agxToneMapping = /*@__PURE__*/(0, _TSLBase.Fn)(([color, exposure]) => { const colortone = (0, _TSLBase.vec3)(color).toVar(); const AgXInsetMatrix = (0, _TSLBase.mat3)((0, _TSLBase.vec3)(0.856627153315983, 0.137318972929847, 0.11189821299995), (0, _TSLBase.vec3)(0.0951212405381588, 0.761241990602591, 0.0767994186031903), (0, _TSLBase.vec3)(0.0482516061458583, 0.101439036467562, 0.811302368396859)); const AgXOutsetMatrix = (0, _TSLBase.mat3)((0, _TSLBase.vec3)(1.1271005818144368, -0.1413297634984383, -0.14132976349843826), (0, _TSLBase.vec3)(-0.11060664309660323, 1.157823702216272, -0.11060664309660294), (0, _TSLBase.vec3)(-0.016493938717834573, -0.016493938717834257, 1.2519364065950405)); const AgxMinEv = (0, _TSLBase.float)(-12.47393); const AgxMaxEv = (0, _TSLBase.float)(4.026069); colortone.mulAssign(exposure); colortone.assign(LINEAR_SRGB_TO_LINEAR_REC2020.mul(colortone)); colortone.assign(AgXInsetMatrix.mul(colortone)); colortone.assign((0, _MathNode.max)(colortone, 1e-10)); colortone.assign((0, _MathNode.log2)(colortone)); colortone.assign(colortone.sub(AgxMinEv).div(AgxMaxEv.sub(AgxMinEv))); colortone.assign((0, _MathNode.clamp)(colortone, 0.0, 1.0)); colortone.assign(agxDefaultContrastApprox(colortone)); colortone.assign(AgXOutsetMatrix.mul(colortone)); colortone.assign((0, _MathNode.pow)((0, _MathNode.max)((0, _TSLBase.vec3)(0.0), colortone), (0, _TSLBase.vec3)(2.2))); colortone.assign(LINEAR_REC2020_TO_LINEAR_SRGB.mul(colortone)); colortone.assign((0, _MathNode.clamp)(colortone, 0.0, 1.0)); return colortone; }).setLayout({ name: 'agxToneMapping', type: 'vec3', inputs: [{ name: 'color', type: 'vec3' }, { name: 'exposure', type: 'float' }] }); /** * Neutral tone mapping. * * Reference: {@link https://modelviewer.dev/examples/tone-mapping} * * @tsl * @function * @param {Node<vec3>} color - The color that should be tone mapped. * @param {Node<float>} exposure - The exposure. * @return {Node<vec3>} The tone mapped color. */ const neutralToneMapping = exports.neutralToneMapping = /*@__PURE__*/(0, _TSLBase.Fn)(([color, exposure]) => { const StartCompression = (0, _TSLBase.float)(0.8 - 0.04); const Desaturation = (0, _TSLBase.float)(0.15); color = color.mul(exposure); const x = (0, _MathNode.min)(color.r, (0, _MathNode.min)(color.g, color.b)); const offset = (0, _ConditionalNode.select)(x.lessThan(0.08), x.sub((0, _OperatorNode.mul)(6.25, x.mul(x))), 0.04); color.subAssign(offset); const peak = (0, _MathNode.max)(color.r, (0, _MathNode.max)(color.g, color.b)); (0, _TSLBase.If)(peak.lessThan(StartCompression), () => { return color; }); const d = (0, _OperatorNode.sub)(1, StartCompression); const newPeak = (0, _OperatorNode.sub)(1, d.mul(d).div(peak.add(d.sub(StartCompression)))); color.mulAssign(newPeak.div(peak)); const g = (0, _OperatorNode.sub)(1, (0, _OperatorNode.div)(1, Desaturation.mul(peak.sub(newPeak)).add(1))); return (0, _MathNode.mix)(color, (0, _TSLBase.vec3)(newPeak), g); }).setLayout({ name: 'neutralToneMapping', type: 'vec3', inputs: [{ name: 'color', type: 'vec3' }, { name: 'exposure', type: 'float' }] });