UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

126 lines (118 loc) 3.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.normalMap = exports.default = void 0; var _TempNode = _interopRequireDefault(require("../core/TempNode.js")); var _OperatorNode = require("../math/OperatorNode.js"); var _Normal = require("../accessors/Normal.js"); var _Position = require("../accessors/Position.js"); var _AccessorsUtils = require("../accessors/AccessorsUtils.js"); var _UV = require("../accessors/UV.js"); var _FrontFacingNode = require("./FrontFacingNode.js"); var _TSLBase = require("../tsl/TSLBase.js"); var _constants = require("../../constants.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // Normal Mapping Without Precomputed Tangents // http://www.thetenthplanet.de/archives/1180 const perturbNormal2Arb = /*@__PURE__*/(0, _TSLBase.Fn)(inputs => { const { eye_pos, surf_norm, mapN, uv } = inputs; const q0 = eye_pos.dFdx(); const q1 = eye_pos.dFdy(); const st0 = uv.dFdx(); const st1 = uv.dFdy(); const N = surf_norm; // normalized const q1perp = q1.cross(N); const q0perp = N.cross(q0); const T = q1perp.mul(st0.x).add(q0perp.mul(st1.x)); const B = q1perp.mul(st0.y).add(q0perp.mul(st1.y)); const det = T.dot(T).max(B.dot(B)); const scale = _FrontFacingNode.faceDirection.mul(det.inverseSqrt()); return (0, _OperatorNode.add)(T.mul(mapN.x, scale), B.mul(mapN.y, scale), N.mul(mapN.z)).normalize(); }); /** * This class can be used for applying normals maps to materials. * * ```js * material.normalNode = normalMap( texture( normalTex ) ); * ``` * * @augments TempNode */ class NormalMapNode extends _TempNode.default { static get type() { return 'NormalMapNode'; } /** * Constructs a new normal map node. * * @param {Node<vec3>} node - Represents the normal map data. * @param {?Node<vec2>} [scaleNode=null] - Controls the intensity of the effect. */ constructor(node, scaleNode = null) { super('vec3'); /** * Represents the normal map data. * * @type {Node<vec3>} */ this.node = node; /** * Controls the intensity of the effect. * * @type {?Node<vec2>} * @default null */ this.scaleNode = scaleNode; /** * The normal map type. * * @type {(TangentSpaceNormalMap|ObjectSpaceNormalMap)} * @default TangentSpaceNormalMap */ this.normalMapType = _constants.TangentSpaceNormalMap; } setup(builder) { const { normalMapType, scaleNode } = this; let normalMap = this.node.mul(2.0).sub(1.0); if (scaleNode !== null) { normalMap = (0, _TSLBase.vec3)(normalMap.xy.mul(scaleNode), normalMap.z); } let outputNode = null; if (normalMapType === _constants.ObjectSpaceNormalMap) { outputNode = (0, _Normal.transformNormalToView)(normalMap); } else if (normalMapType === _constants.TangentSpaceNormalMap) { const tangent = builder.hasGeometryAttribute('tangent'); if (tangent === true) { outputNode = _AccessorsUtils.TBNViewMatrix.mul(normalMap).normalize(); } else { outputNode = perturbNormal2Arb({ eye_pos: _Position.positionView, surf_norm: _Normal.normalView, mapN: normalMap, uv: (0, _UV.uv)() }); } } return outputNode; } } var _default = exports.default = NormalMapNode; /** * TSL function for creating a normal map node. * * @tsl * @function * @param {Node<vec3>} node - Represents the normal map data. * @param {?Node<vec2>} [scaleNode=null] - Controls the intensity of the effect. * @returns {NormalMapNode} */ const normalMap = exports.normalMap = /*@__PURE__*/(0, _TSLBase.nodeProxy)(NormalMapNode).setParameterLength(1, 2);