@openhps/core
Version:
Open Hybrid Positioning System - Core component
81 lines (78 loc) • 5.18 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getViewPosition = exports.getScreenPosition = exports.getNormalFromDepth = void 0;
var _TSLBase = require("../tsl/TSLBase.js");
var _TextureSizeNode = require("../accessors/TextureSizeNode.js");
var _TextureNode = require("../accessors/TextureNode.js");
var _constants = require("../../constants.js");
/**
* Computes a position in view space based on a fragment's screen position expressed as uv coordinates, the fragments
* depth value and the camera's inverse projection matrix.
*
* @tsl
* @function
* @param {Node<vec2>} screenPosition - The fragment's screen position expressed as uv coordinates.
* @param {Node<float>} depth - The fragment's depth value.
* @param {Node<mat4>} projectionMatrixInverse - The camera's inverse projection matrix.
* @return {Node<vec3>} The fragments position in view space.
*/
const getViewPosition = exports.getViewPosition = /*@__PURE__*/(0, _TSLBase.Fn)(([screenPosition, depth, projectionMatrixInverse], builder) => {
let clipSpacePosition;
if (builder.renderer.coordinateSystem === _constants.WebGPUCoordinateSystem) {
screenPosition = (0, _TSLBase.vec2)(screenPosition.x, screenPosition.y.oneMinus()).mul(2.0).sub(1.0);
clipSpacePosition = (0, _TSLBase.vec4)((0, _TSLBase.vec3)(screenPosition, depth), 1.0);
} else {
clipSpacePosition = (0, _TSLBase.vec4)((0, _TSLBase.vec3)(screenPosition.x, screenPosition.y.oneMinus(), depth).mul(2.0).sub(1.0), 1.0);
}
const viewSpacePosition = (0, _TSLBase.vec4)(projectionMatrixInverse.mul(clipSpacePosition));
return viewSpacePosition.xyz.div(viewSpacePosition.w);
});
/**
* Computes a screen position expressed as uv coordinates based on a fragment's position in view space
* and the camera's projection matrix
*
* @tsl
* @function
* @param {Node<vec3>} viewPosition - The fragments position in view space.
* @param {Node<mat4>} projectionMatrix - The camera's projection matrix.
* @return {Node<vec2>} The fragment's screen position expressed as uv coordinates.
*/
const getScreenPosition = exports.getScreenPosition = /*@__PURE__*/(0, _TSLBase.Fn)(([viewPosition, projectionMatrix]) => {
const sampleClipPos = projectionMatrix.mul((0, _TSLBase.vec4)(viewPosition, 1.0));
const sampleUv = sampleClipPos.xy.div(sampleClipPos.w).mul(0.5).add(0.5).toVar();
return (0, _TSLBase.vec2)(sampleUv.x, sampleUv.y.oneMinus());
});
/**
* Computes a normal vector based on depth data. Can be used as a fallback when no normal render
* target is available or if flat surface normals are required.
*
* @tsl
* @function
* @param {Node<vec2>} uv - The texture coordinate.
* @param {DepthTexture} depthTexture - The depth texture.
* @param {Node<mat4>} projectionMatrixInverse - The camera's inverse projection matrix.
* @return {Node<vec3>} The computed normal vector.
*/
const getNormalFromDepth = exports.getNormalFromDepth = /*@__PURE__*/(0, _TSLBase.Fn)(([uv, depthTexture, projectionMatrixInverse]) => {
const size = (0, _TextureSizeNode.textureSize)((0, _TextureNode.textureLoad)(depthTexture));
const p = (0, _TSLBase.ivec2)(uv.mul(size)).toVar();
const c0 = (0, _TextureNode.textureLoad)(depthTexture, p).toVar();
const l2 = (0, _TextureNode.textureLoad)(depthTexture, p.sub((0, _TSLBase.ivec2)(2, 0))).toVar();
const l1 = (0, _TextureNode.textureLoad)(depthTexture, p.sub((0, _TSLBase.ivec2)(1, 0))).toVar();
const r1 = (0, _TextureNode.textureLoad)(depthTexture, p.add((0, _TSLBase.ivec2)(1, 0))).toVar();
const r2 = (0, _TextureNode.textureLoad)(depthTexture, p.add((0, _TSLBase.ivec2)(2, 0))).toVar();
const b2 = (0, _TextureNode.textureLoad)(depthTexture, p.add((0, _TSLBase.ivec2)(0, 2))).toVar();
const b1 = (0, _TextureNode.textureLoad)(depthTexture, p.add((0, _TSLBase.ivec2)(0, 1))).toVar();
const t1 = (0, _TextureNode.textureLoad)(depthTexture, p.sub((0, _TSLBase.ivec2)(0, 1))).toVar();
const t2 = (0, _TextureNode.textureLoad)(depthTexture, p.sub((0, _TSLBase.ivec2)(0, 2))).toVar();
const dl = (0, _TSLBase.abs)((0, _TSLBase.sub)((0, _TSLBase.float)(2).mul(l1).sub(l2), c0)).toVar();
const dr = (0, _TSLBase.abs)((0, _TSLBase.sub)((0, _TSLBase.float)(2).mul(r1).sub(r2), c0)).toVar();
const db = (0, _TSLBase.abs)((0, _TSLBase.sub)((0, _TSLBase.float)(2).mul(b1).sub(b2), c0)).toVar();
const dt = (0, _TSLBase.abs)((0, _TSLBase.sub)((0, _TSLBase.float)(2).mul(t1).sub(t2), c0)).toVar();
const ce = getViewPosition(uv, c0, projectionMatrixInverse).toVar();
const dpdx = dl.lessThan(dr).select(ce.sub(getViewPosition(uv.sub((0, _TSLBase.vec2)((0, _TSLBase.float)(1).div(size.x), 0)), l1, projectionMatrixInverse)), ce.negate().add(getViewPosition(uv.add((0, _TSLBase.vec2)((0, _TSLBase.float)(1).div(size.x), 0)), r1, projectionMatrixInverse)));
const dpdy = db.lessThan(dt).select(ce.sub(getViewPosition(uv.add((0, _TSLBase.vec2)(0, (0, _TSLBase.float)(1).div(size.y))), b1, projectionMatrixInverse)), ce.negate().add(getViewPosition(uv.sub((0, _TSLBase.vec2)(0, (0, _TSLBase.float)(1).div(size.y))), t1, projectionMatrixInverse)));
return (0, _TSLBase.normalize)((0, _TSLBase.cross)(dpdx, dpdy));
});