UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

160 lines (144 loc) 5.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.toonOutlinePass = exports.default = void 0; var _TSLBase = require("../tsl/TSLBase.js"); var _Color = require("../../math/Color.js"); var _NodeMaterial = _interopRequireDefault(require("../../materials/nodes/NodeMaterial.js")); var _Camera = require("../../nodes/accessors/Camera.js"); var _ModelNode = require("../../nodes/accessors/ModelNode.js"); var _Position = require("../../nodes/accessors/Position.js"); var _Normal = require("../../nodes/accessors/Normal.js"); var _constants = require("../../constants.js"); var _PassNode = _interopRequireDefault(require("./PassNode.js")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Represents a render pass for producing a toon outline effect on compatible objects. * Only 3D objects with materials of type `MeshToonMaterial` and `MeshToonNodeMaterial` * will receive the outline. * * ```js * const postProcessing = new PostProcessing( renderer ); * * const scenePass = toonOutlinePass( scene, camera ); * * postProcessing.outputNode = scenePass; * ``` * @augments PassNode */ class ToonOutlinePassNode extends _PassNode.default { static get type() { return 'ToonOutlinePassNode'; } /** * Constructs a new outline pass node. * * @param {Scene} scene - A reference to the scene. * @param {Camera} camera - A reference to the camera. * @param {Node} colorNode - Defines the outline's color. * @param {Node} thicknessNode - Defines the outline's thickness. * @param {Node} alphaNode - Defines the outline's alpha. */ constructor(scene, camera, colorNode, thicknessNode, alphaNode) { super(_PassNode.default.COLOR, scene, camera); /** * Defines the outline's color. * * @type {Node} */ this.colorNode = colorNode; /** * Defines the outline's thickness. * * @type {Node} */ this.thicknessNode = thicknessNode; /** * Defines the outline's alpha. * * @type {Node} */ this.alphaNode = alphaNode; /** * An internal material cache. * * @private * @type {WeakMap<Material, NodeMaterial>} */ this._materialCache = new WeakMap(); } updateBefore(frame) { const { renderer } = frame; const currentRenderObjectFunction = renderer.getRenderObjectFunction(); renderer.setRenderObjectFunction((object, scene, camera, geometry, material, group, lightsNode, clippingContext) => { // only render outline for supported materials if (material.isMeshToonMaterial || material.isMeshToonNodeMaterial) { if (material.wireframe === false) { const outlineMaterial = this._getOutlineMaterial(material); renderer.renderObject(object, scene, camera, geometry, outlineMaterial, group, lightsNode, clippingContext); } } // default renderer.renderObject(object, scene, camera, geometry, material, group, lightsNode, clippingContext); }); super.updateBefore(frame); renderer.setRenderObjectFunction(currentRenderObjectFunction); } /** * Creates the material used for outline rendering. * * @private * @return {NodeMaterial} The outline material. */ _createMaterial() { const material = new _NodeMaterial.default(); material.isMeshToonOutlineMaterial = true; material.name = 'Toon_Outline'; material.side = _constants.BackSide; // vertex node const outlineNormal = _Normal.normalLocal.negate(); const mvp = _Camera.cameraProjectionMatrix.mul(_ModelNode.modelViewMatrix); const ratio = (0, _TSLBase.float)(1.0); // TODO: support outline thickness ratio for each vertex const pos = mvp.mul((0, _TSLBase.vec4)(_Position.positionLocal, 1.0)); const pos2 = mvp.mul((0, _TSLBase.vec4)(_Position.positionLocal.add(outlineNormal), 1.0)); const norm = (0, _TSLBase.normalize)(pos.sub(pos2)); // NOTE: subtract pos2 from pos because BackSide objectNormal is negative material.vertexNode = pos.add(norm.mul(this.thicknessNode).mul(pos.w).mul(ratio)); // color node material.colorNode = (0, _TSLBase.vec4)(this.colorNode, this.alphaNode); return material; } /** * For the given toon material, this method returns a corresponding * outline material. * * @private * @param {(MeshToonMaterial|MeshToonNodeMaterial)} originalMaterial - The toon material. * @return {NodeMaterial} The outline material. */ _getOutlineMaterial(originalMaterial) { let outlineMaterial = this._materialCache.get(originalMaterial); if (outlineMaterial === undefined) { outlineMaterial = this._createMaterial(); this._materialCache.set(originalMaterial, outlineMaterial); } return outlineMaterial; } } var _default = exports.default = ToonOutlinePassNode; /** * TSL function for creating a toon outline pass node. * * @tsl * @function * @param {Scene} scene - A reference to the scene. * @param {Camera} camera - A reference to the camera. * @param {Color} color - Defines the outline's color. * @param {number} [thickness=0.003] - Defines the outline's thickness. * @param {number} [alpha=1] - Defines the outline's alpha. * @returns {ToonOutlinePassNode} */ const toonOutlinePass = (scene, camera, color = new _Color.Color(0, 0, 0), thickness = 0.003, alpha = 1) => (0, _TSLBase.nodeObject)(new ToonOutlinePassNode(scene, camera, (0, _TSLBase.nodeObject)(color), (0, _TSLBase.nodeObject)(thickness), (0, _TSLBase.nodeObject)(alpha))); exports.toonOutlinePass = toonOutlinePass;