@openhps/core
Version:
Open Hybrid Positioning System - Core component
47 lines (37 loc) • 2.12 kB
JavaScript
import { abs, add, ceil, clamp, dFdx, dFdy, exp2, float, floor, Fn, fract, length, log2, max, min, mul, sin, sub, vec2, vec3 } from '../../tsl/TSLBase.js';
// See: https://casual-effects.com/research/Wyman2017Hashed/index.html
const ALPHA_HASH_SCALE = 0.05; // Derived from trials only, and may be changed.
const hash2D = /*@__PURE__*/Fn(([value]) => {
return fract(mul(1.0e4, sin(mul(17.0, value.x).add(mul(0.1, value.y)))).mul(add(0.1, abs(sin(mul(13.0, value.y).add(value.x))))));
});
const hash3D = /*@__PURE__*/Fn(([value]) => {
return hash2D(vec2(hash2D(value.xy), value.z));
});
const getAlphaHashThreshold = /*@__PURE__*/Fn(([position]) => {
// Find the discretized derivatives of our coordinates
const maxDeriv = max(length(dFdx(position.xyz)), length(dFdy(position.xyz)));
const pixScale = float(1).div(float(ALPHA_HASH_SCALE).mul(maxDeriv)).toVar('pixScale');
// Find two nearest log-discretized noise scales
const pixScales = vec2(exp2(floor(log2(pixScale))), exp2(ceil(log2(pixScale))));
// Compute alpha thresholds at our two noise scales
const alpha = vec2(hash3D(floor(pixScales.x.mul(position.xyz))), hash3D(floor(pixScales.y.mul(position.xyz))));
// Factor to interpolate lerp with
const lerpFactor = fract(log2(pixScale));
// Interpolate alpha threshold from noise at two scales
const x = add(mul(lerpFactor.oneMinus(), alpha.x), mul(lerpFactor, alpha.y));
// Pass into CDF to compute uniformly distrib threshold
const a = min(lerpFactor, lerpFactor.oneMinus());
const cases = vec3(x.mul(x).div(mul(2.0, a).mul(sub(1.0, a))), x.sub(mul(0.5, a)).div(sub(1.0, a)), sub(1.0, sub(1.0, x).mul(sub(1.0, x)).div(mul(2.0, a).mul(sub(1.0, a)))));
// Find our final, uniformly distributed alpha threshold (ατ)
const threshold = x.lessThan(a.oneMinus()).select(x.lessThan(a).select(cases.x, cases.y), cases.z);
// Avoids ατ == 0. Could also do ατ =1-ατ
return clamp(threshold, 1.0e-6, 1.0);
}).setLayout({
name: 'getAlphaHashThreshold',
type: 'float',
inputs: [{
name: 'position',
type: 'vec3'
}]
});
export default getAlphaHashThreshold;