UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

254 lines (245 loc) 10.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.textureCubeUV = exports.getDirection = exports.blur = void 0; var _TSLBase = require("../tsl/TSLBase.js"); var _MathNode = require("../math/MathNode.js"); var _OperatorNode = require("../math/OperatorNode.js"); var _ConditionalNode = require("../math/ConditionalNode.js"); var _LoopNode = require("../utils/LoopNode.js"); // These defines must match with PMREMGenerator const cubeUV_r0 = /*@__PURE__*/(0, _TSLBase.float)(1.0); const cubeUV_m0 = /*@__PURE__*/(0, _TSLBase.float)(-2.0); const cubeUV_r1 = /*@__PURE__*/(0, _TSLBase.float)(0.8); const cubeUV_m1 = /*@__PURE__*/(0, _TSLBase.float)(-1.0); const cubeUV_r4 = /*@__PURE__*/(0, _TSLBase.float)(0.4); const cubeUV_m4 = /*@__PURE__*/(0, _TSLBase.float)(2.0); const cubeUV_r5 = /*@__PURE__*/(0, _TSLBase.float)(0.305); const cubeUV_m5 = /*@__PURE__*/(0, _TSLBase.float)(3.0); const cubeUV_r6 = /*@__PURE__*/(0, _TSLBase.float)(0.21); const cubeUV_m6 = /*@__PURE__*/(0, _TSLBase.float)(4.0); const cubeUV_minMipLevel = /*@__PURE__*/(0, _TSLBase.float)(4.0); const cubeUV_minTileSize = /*@__PURE__*/(0, _TSLBase.float)(16.0); // These shader functions convert between the UV coordinates of a single face of // a cubemap, the 0-5 integer index of a cube face, and the direction vector for // sampling a textureCube (not generally normalized ). const getFace = /*@__PURE__*/(0, _TSLBase.Fn)(([direction]) => { const absDirection = (0, _TSLBase.vec3)((0, _MathNode.abs)(direction)).toVar(); const face = (0, _TSLBase.float)(-1.0).toVar(); (0, _TSLBase.If)(absDirection.x.greaterThan(absDirection.z), () => { (0, _TSLBase.If)(absDirection.x.greaterThan(absDirection.y), () => { face.assign((0, _ConditionalNode.select)(direction.x.greaterThan(0.0), 0.0, 3.0)); }).Else(() => { face.assign((0, _ConditionalNode.select)(direction.y.greaterThan(0.0), 1.0, 4.0)); }); }).Else(() => { (0, _TSLBase.If)(absDirection.z.greaterThan(absDirection.y), () => { face.assign((0, _ConditionalNode.select)(direction.z.greaterThan(0.0), 2.0, 5.0)); }).Else(() => { face.assign((0, _ConditionalNode.select)(direction.y.greaterThan(0.0), 1.0, 4.0)); }); }); return face; }).setLayout({ name: 'getFace', type: 'float', inputs: [{ name: 'direction', type: 'vec3' }] }); // RH coordinate system; PMREM face-indexing convention const getUV = /*@__PURE__*/(0, _TSLBase.Fn)(([direction, face]) => { const uv = (0, _TSLBase.vec2)().toVar(); (0, _TSLBase.If)(face.equal(0.0), () => { uv.assign((0, _TSLBase.vec2)(direction.z, direction.y).div((0, _MathNode.abs)(direction.x))); // pos x }).ElseIf(face.equal(1.0), () => { uv.assign((0, _TSLBase.vec2)(direction.x.negate(), direction.z.negate()).div((0, _MathNode.abs)(direction.y))); // pos y }).ElseIf(face.equal(2.0), () => { uv.assign((0, _TSLBase.vec2)(direction.x.negate(), direction.y).div((0, _MathNode.abs)(direction.z))); // pos z }).ElseIf(face.equal(3.0), () => { uv.assign((0, _TSLBase.vec2)(direction.z.negate(), direction.y).div((0, _MathNode.abs)(direction.x))); // neg x }).ElseIf(face.equal(4.0), () => { uv.assign((0, _TSLBase.vec2)(direction.x.negate(), direction.z).div((0, _MathNode.abs)(direction.y))); // neg y }).Else(() => { uv.assign((0, _TSLBase.vec2)(direction.x, direction.y).div((0, _MathNode.abs)(direction.z))); // neg z }); return (0, _OperatorNode.mul)(0.5, uv.add(1.0)); }).setLayout({ name: 'getUV', type: 'vec2', inputs: [{ name: 'direction', type: 'vec3' }, { name: 'face', type: 'float' }] }); const roughnessToMip = /*@__PURE__*/(0, _TSLBase.Fn)(([roughness]) => { const mip = (0, _TSLBase.float)(0.0).toVar(); (0, _TSLBase.If)(roughness.greaterThanEqual(cubeUV_r1), () => { mip.assign(cubeUV_r0.sub(roughness).mul(cubeUV_m1.sub(cubeUV_m0)).div(cubeUV_r0.sub(cubeUV_r1)).add(cubeUV_m0)); }).ElseIf(roughness.greaterThanEqual(cubeUV_r4), () => { mip.assign(cubeUV_r1.sub(roughness).mul(cubeUV_m4.sub(cubeUV_m1)).div(cubeUV_r1.sub(cubeUV_r4)).add(cubeUV_m1)); }).ElseIf(roughness.greaterThanEqual(cubeUV_r5), () => { mip.assign(cubeUV_r4.sub(roughness).mul(cubeUV_m5.sub(cubeUV_m4)).div(cubeUV_r4.sub(cubeUV_r5)).add(cubeUV_m4)); }).ElseIf(roughness.greaterThanEqual(cubeUV_r6), () => { mip.assign(cubeUV_r5.sub(roughness).mul(cubeUV_m6.sub(cubeUV_m5)).div(cubeUV_r5.sub(cubeUV_r6)).add(cubeUV_m5)); }).Else(() => { mip.assign((0, _TSLBase.float)(-2.0).mul((0, _MathNode.log2)((0, _OperatorNode.mul)(1.16, roughness)))); // 1.16 = 1.79^0.25 }); return mip; }).setLayout({ name: 'roughnessToMip', type: 'float', inputs: [{ name: 'roughness', type: 'float' }] }); // RH coordinate system; PMREM face-indexing convention const getDirection = exports.getDirection = /*@__PURE__*/(0, _TSLBase.Fn)(([uv_immutable, face]) => { const uv = uv_immutable.toVar(); uv.assign((0, _OperatorNode.mul)(2.0, uv).sub(1.0)); const direction = (0, _TSLBase.vec3)(uv, 1.0).toVar(); (0, _TSLBase.If)(face.equal(0.0), () => { direction.assign(direction.zyx); // ( 1, v, u ) pos x }).ElseIf(face.equal(1.0), () => { direction.assign(direction.xzy); direction.xz.mulAssign(-1.0); // ( -u, 1, -v ) pos y }).ElseIf(face.equal(2.0), () => { direction.x.mulAssign(-1.0); // ( -u, v, 1 ) pos z }).ElseIf(face.equal(3.0), () => { direction.assign(direction.zyx); direction.xz.mulAssign(-1.0); // ( -1, v, -u ) neg x }).ElseIf(face.equal(4.0), () => { direction.assign(direction.xzy); direction.xy.mulAssign(-1.0); // ( -u, -1, v ) neg y }).ElseIf(face.equal(5.0), () => { direction.z.mulAssign(-1.0); // ( u, v, -1 ) neg zS }); return direction; }).setLayout({ name: 'getDirection', type: 'vec3', inputs: [{ name: 'uv', type: 'vec2' }, { name: 'face', type: 'float' }] }); // const textureCubeUV = exports.textureCubeUV = /*@__PURE__*/(0, _TSLBase.Fn)(([envMap, sampleDir_immutable, roughness_immutable, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP]) => { const roughness = (0, _TSLBase.float)(roughness_immutable); const sampleDir = (0, _TSLBase.vec3)(sampleDir_immutable); const mip = (0, _MathNode.clamp)(roughnessToMip(roughness), cubeUV_m0, CUBEUV_MAX_MIP); const mipF = (0, _MathNode.fract)(mip); const mipInt = (0, _MathNode.floor)(mip); const color0 = (0, _TSLBase.vec3)(bilinearCubeUV(envMap, sampleDir, mipInt, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP)).toVar(); (0, _TSLBase.If)(mipF.notEqual(0.0), () => { const color1 = (0, _TSLBase.vec3)(bilinearCubeUV(envMap, sampleDir, mipInt.add(1.0), CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP)).toVar(); color0.assign((0, _MathNode.mix)(color0, color1, mipF)); }); return color0; }); const bilinearCubeUV = /*@__PURE__*/(0, _TSLBase.Fn)(([envMap, direction_immutable, mipInt_immutable, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP]) => { const mipInt = (0, _TSLBase.float)(mipInt_immutable).toVar(); const direction = (0, _TSLBase.vec3)(direction_immutable); const face = (0, _TSLBase.float)(getFace(direction)).toVar(); const filterInt = (0, _TSLBase.float)((0, _MathNode.max)(cubeUV_minMipLevel.sub(mipInt), 0.0)).toVar(); mipInt.assign((0, _MathNode.max)(mipInt, cubeUV_minMipLevel)); const faceSize = (0, _TSLBase.float)((0, _MathNode.exp2)(mipInt)).toVar(); const uv = (0, _TSLBase.vec2)(getUV(direction, face).mul(faceSize.sub(2.0)).add(1.0)).toVar(); (0, _TSLBase.If)(face.greaterThan(2.0), () => { uv.y.addAssign(faceSize); face.subAssign(3.0); }); uv.x.addAssign(face.mul(faceSize)); uv.x.addAssign(filterInt.mul((0, _OperatorNode.mul)(3.0, cubeUV_minTileSize))); uv.y.addAssign((0, _OperatorNode.mul)(4.0, (0, _MathNode.exp2)(CUBEUV_MAX_MIP).sub(faceSize))); uv.x.mulAssign(CUBEUV_TEXEL_WIDTH); uv.y.mulAssign(CUBEUV_TEXEL_HEIGHT); return envMap.sample(uv).grad((0, _TSLBase.vec2)(), (0, _TSLBase.vec2)()); // disable anisotropic filtering }); const getSample = /*@__PURE__*/(0, _TSLBase.Fn)(({ envMap, mipInt, outputDirection, theta, axis, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }) => { const cosTheta = (0, _MathNode.cos)(theta); // Rodrigues' axis-angle rotation const sampleDirection = outputDirection.mul(cosTheta).add(axis.cross(outputDirection).mul((0, _MathNode.sin)(theta))).add(axis.mul(axis.dot(outputDirection).mul(cosTheta.oneMinus()))); return bilinearCubeUV(envMap, sampleDirection, mipInt, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP); }); const blur = exports.blur = /*@__PURE__*/(0, _TSLBase.Fn)(({ n, latitudinal, poleAxis, outputDirection, weights, samples, dTheta, mipInt, envMap, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }) => { const axis = (0, _TSLBase.vec3)((0, _ConditionalNode.select)(latitudinal, poleAxis, (0, _MathNode.cross)(poleAxis, outputDirection))).toVar(); (0, _TSLBase.If)(axis.equal((0, _TSLBase.vec3)(0.0)), () => { axis.assign((0, _TSLBase.vec3)(outputDirection.z, 0.0, outputDirection.x.negate())); }); axis.assign((0, _MathNode.normalize)(axis)); const gl_FragColor = (0, _TSLBase.vec3)().toVar(); gl_FragColor.addAssign(weights.element(0).mul(getSample({ theta: 0.0, axis, outputDirection, mipInt, envMap, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }))); (0, _LoopNode.Loop)({ start: (0, _TSLBase.int)(1), end: n }, ({ i }) => { (0, _TSLBase.If)(i.greaterThanEqual(samples), () => { (0, _LoopNode.Break)(); }); const theta = (0, _TSLBase.float)(dTheta.mul((0, _TSLBase.float)(i))).toVar(); gl_FragColor.addAssign(weights.element(i).mul(getSample({ theta: theta.mul(-1.0), axis, outputDirection, mipInt, envMap, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }))); gl_FragColor.addAssign(weights.element(i).mul(getSample({ theta, axis, outputDirection, mipInt, envMap, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }))); }); return (0, _TSLBase.vec4)(gl_FragColor, 1); });