@openhps/core
Version:
Open Hybrid Positioning System - Core component
61 lines (57 loc) • 3.24 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.textureBicubic = void 0;
var _OperatorNode = require("../math/OperatorNode.js");
var _MathNode = require("../math/MathNode.js");
var _TSLBase = require("../tsl/TSLBase.js");
// Mipped Bicubic Texture Filtering by N8
// https://www.shadertoy.com/view/Dl2SDW
const bC = 1.0 / 6.0;
const w0 = a => (0, _OperatorNode.mul)(bC, (0, _OperatorNode.mul)(a, (0, _OperatorNode.mul)(a, a.negate().add(3.0)).sub(3.0)).add(1.0));
const w1 = a => (0, _OperatorNode.mul)(bC, (0, _OperatorNode.mul)(a, (0, _OperatorNode.mul)(a, (0, _OperatorNode.mul)(3.0, a).sub(6.0))).add(4.0));
const w2 = a => (0, _OperatorNode.mul)(bC, (0, _OperatorNode.mul)(a, (0, _OperatorNode.mul)(a, (0, _OperatorNode.mul)(-3.0, a).add(3.0)).add(3.0)).add(1.0));
const w3 = a => (0, _OperatorNode.mul)(bC, (0, _MathNode.pow)(a, 3));
const g0 = a => w0(a).add(w1(a));
const g1 = a => w2(a).add(w3(a));
// h0 and h1 are the two offset functions
const h0 = a => (0, _OperatorNode.add)(-1.0, w1(a).div(w0(a).add(w1(a))));
const h1 = a => (0, _OperatorNode.add)(1.0, w3(a).div(w2(a).add(w3(a))));
const bicubic = (textureNode, texelSize, lod) => {
const uv = textureNode.uvNode;
const uvScaled = (0, _OperatorNode.mul)(uv, texelSize.zw).add(0.5);
const iuv = (0, _MathNode.floor)(uvScaled);
const fuv = (0, _MathNode.fract)(uvScaled);
const g0x = g0(fuv.x);
const g1x = g1(fuv.x);
const h0x = h0(fuv.x);
const h1x = h1(fuv.x);
const h0y = h0(fuv.y);
const h1y = h1(fuv.y);
const p0 = (0, _TSLBase.vec2)(iuv.x.add(h0x), iuv.y.add(h0y)).sub(0.5).mul(texelSize.xy);
const p1 = (0, _TSLBase.vec2)(iuv.x.add(h1x), iuv.y.add(h0y)).sub(0.5).mul(texelSize.xy);
const p2 = (0, _TSLBase.vec2)(iuv.x.add(h0x), iuv.y.add(h1y)).sub(0.5).mul(texelSize.xy);
const p3 = (0, _TSLBase.vec2)(iuv.x.add(h1x), iuv.y.add(h1y)).sub(0.5).mul(texelSize.xy);
const a = g0(fuv.y).mul((0, _OperatorNode.add)(g0x.mul(textureNode.sample(p0).level(lod)), g1x.mul(textureNode.sample(p1).level(lod))));
const b = g1(fuv.y).mul((0, _OperatorNode.add)(g0x.mul(textureNode.sample(p2).level(lod)), g1x.mul(textureNode.sample(p3).level(lod))));
return a.add(b);
};
/**
* Applies mipped bicubic texture filtering to the given texture node.
*
* @tsl
* @function
* @param {TextureNode} textureNode - The texture node that should be filtered.
* @param {Node<float>} [lodNode=float(3)] - Defines the LOD to sample from.
* @return {Node} The filtered texture sample.
*/
const textureBicubic = exports.textureBicubic = /*@__PURE__*/(0, _TSLBase.Fn)(([textureNode, lodNode = (0, _TSLBase.float)(3)]) => {
const fLodSize = (0, _TSLBase.vec2)(textureNode.size((0, _TSLBase.int)(lodNode)));
const cLodSize = (0, _TSLBase.vec2)(textureNode.size((0, _TSLBase.int)(lodNode.add(1.0))));
const fLodSizeInv = (0, _OperatorNode.div)(1.0, fLodSize);
const cLodSizeInv = (0, _OperatorNode.div)(1.0, cLodSize);
const fSample = bicubic(textureNode, (0, _TSLBase.vec4)(fLodSizeInv, fLodSize), (0, _MathNode.floor)(lodNode));
const cSample = bicubic(textureNode, (0, _TSLBase.vec4)(cLodSizeInv, cLodSize), (0, _MathNode.ceil)(lodNode));
return (0, _MathNode.fract)(lodNode).mix(fSample, cSample);
});