@openhps/core
Version:
Open Hybrid Positioning System - Core component
126 lines (118 loc) • 3.79 kB
JavaScript
;
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);