@openhps/core
Version:
Open Hybrid Positioning System - Core component
221 lines (210 loc) • 8.41 kB
JavaScript
"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'
}]
});