UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

238 lines (192 loc) 12.6 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var THREE = _interopRequireWildcard(require("three")); var _Capabilities = _interopRequireDefault(require("../Core/System/Capabilities")); var _ShaderUtils = _interopRequireDefault(require("./Shader/ShaderUtils")); /* babel-plugin-inline-import './Shader/ProjectiveTextureVS.glsl' */ var textureVS = "#include <itowns/precision_qualifier>\n#include <itowns/project_pars_vertex>\n#include <itowns/projective_texturing_pars_vertex>\n#include <common>\n#include <logdepthbuf_pars_vertex>\n\nvarying vec3 vNormal;\nattribute vec3 normal;\n\nvoid main() {\n #include <begin_vertex>\n #include <project_vertex>\n vNormal = normal;\n #include <itowns/projective_texturing_vertex>\n #include <logdepthbuf_vertex>\n}\n"; /* babel-plugin-inline-import './Shader/ProjectiveTextureFS.glsl' */ var textureFS = "#include <itowns/precision_qualifier>\n#include <logdepthbuf_pars_fragment>\n#include <itowns/projective_texturing_pars_fragment>\nvarying vec3 vNormal;\n\n#ifdef USE_BASE_MATERIAL\nstruct noPT {\n vec3 lightDirection;\n vec3 ambient;\n float opacity;\n};\n\nuniform noPT noProjectiveMaterial;\n#endif\n\nvoid main(void)\n{\n #include <logdepthbuf_fragment>\n #ifdef USE_BASE_MATERIAL\n float nDotVP = (max(0.1, dot(vNormal, normalize(noProjectiveMaterial.lightDirection))));\n vec4 color = vec4(noProjectiveMaterial.ambient + nDotVP, 0.0);\n #else\n vec4 color = vec4(0.0);\n #endif\n\n #pragma unroll_loop\n for (int i = 0; i < ORIENTED_IMAGES_COUNT; i++) {\n color = projectiveTextureColor(projectiveTextureCoords[ ORIENTED_IMAGES_COUNT - 1 - i ], projectiveTextureDistortion[ ORIENTED_IMAGES_COUNT - 1 - i ], projectiveTexture[ ORIENTED_IMAGES_COUNT - 1 - i ], mask[ORIENTED_IMAGES_COUNT - 1 - i], color);\n }\n\n #ifdef USE_BASE_MATERIAL\n color.a = color.a < 1.0 ? max(noProjectiveMaterial.opacity, color.a) : 1.0 ;\n gl_FragColor = vec4(color.rgb, color.a * opacity);\n #else\n gl_FragColor = vec4(color.rgb / color.a, opacity);\n #endif\n\n}\n"; var ndcToTextureMatrix = new THREE.Matrix4().set(1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 2, 0, 0, 0, 0, 2); var noMask = new THREE.DataTexture(new Uint8Array([255, 255, 255]), 1, 1, THREE.RGBFormat, THREE.UnsignedByteType); var noTexture = new THREE.Texture(); var rawShaderMaterial = new THREE.RawShaderMaterial(); /** * @classdesc OrientedImageMaterial is a custom shader material used to do projective texture mapping.<br/> * * This Material is designed to project many textures simultaneously. * Each projected texture setting is stored as an {@link OrientedImageCamera}.<br/> * <br/> * All cameras settings, like distorsion, can be specified in a configuration file. * See [CameraCalibrationParser]{@link module:CameraCalibrationParser.parse} * used to parse a configuration file and create an array of camera.<br/> * <br/> * The current implementation supports the following distortion models : <br/> * - no distortion (polynom==vec3(0),l1l2==vec2(0))<br/> * - radial distortion (polynom!=vec3(0),l1l2==vec2(0)) (see <b>15.2.2 Radial Model</b> in [MicMac doc]{@link https://github.com/micmacIGN/Documentation/blob/master/DocMicMac.pdf}) </br> * - equilinear fish eye distortion (polynom!=vec3(0),l1l2 != vec2(0)) (see <b>15.3.4 Fish eye models</b> in [MicMac doc]{@link https://github.com/micmacIGN/Documentation/blob/master/DocMicMac.pdf}) </br> * (Note: radial decentric parameters P1 are P2 not supported and assumed to be 0).<br/> * <br/> * To get a more comprehensive support of camera Micmac models, you can consider using [three-photogrammetric-camera]{@link https://github.com/mbredif/three-photogrammetric-camera} instead. */ var OrientedImageMaterial = /*#__PURE__*/ function (_THREE$RawShaderMater) { (0, _inherits2["default"])(OrientedImageMaterial, _THREE$RawShaderMater); /** * @constructor * @param { OrientedImageCamera[]} cameras - Array of {@link OrientedImageCamera}. Each camera will project a texture. * [CameraCalibrationParser]{@link module:CameraCalibrationParser.parse} can used to create this array of camera from a configuration file. * @param {Object} [options={}] - Object with one or more properties defining the material's appearance. * Any property of the material (including any property inherited from * [THREE.Material]{@link https://threejs.org/docs/#api/en/materials/Material} and * [THREE.ShaderMaterial]{@link https://threejs.org/docs/#api/en/materials/ShaderMaterial}) can be passed in here. * @param {Number} [options.side=THREE.DoubleSide] - We override default * [THREE.Material.side]{@link https://threejs.org/docs/#api/en/materials/Material.side} from FrontSide to DoubleSide. * @param {Boolean} [options.transparent=true] - We override default * [THREE.Material.transparent]{@link https://threejs.org/docs/#api/en/materials/Material.transparent} from false to true. * @param {Number} [options.opacity=0.1] - We override default * [THREE.Material.opacity]{@link https://threejs.org/docs/#api/en/materials/Material.opacity} from 1 to 0.1. * @param {Number} [options.alphaBorder=20] - Part of the texture that is blended, when texture crosses each other. * For example, 10 means a border as large as 1 / 10 of the size of the texture is used to blend colors. * @param {Number} [options.debugAlphaBorder=0] - Set this option to 1 to see influence of alphaBorder option. */ function OrientedImageMaterial(cameras) { var _this; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; (0, _classCallCheck2["default"])(this, OrientedImageMaterial); options.side = options.side !== undefined ? options.side : THREE.DoubleSide; options.transparent = options.transparent !== undefined ? options.transparent : true; options.opacity = options.opacity !== undefined ? options.opacity : 1; // Filter the rawShaderMaterial options var rawShaderMaterialOptions = {}; for (var key in options) { if (Object.prototype.hasOwnProperty.call(options, key)) { var currentValue = rawShaderMaterial[key]; if (currentValue !== undefined) { rawShaderMaterialOptions[key] = options[key]; } } } _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(OrientedImageMaterial).call(this, rawShaderMaterialOptions)); _this.defines.ORIENTED_IMAGES_COUNT = options.OrientedImagesCount !== undefined ? options.OrientedImagesCount : cameras.length; // verify that number of textures doesn't exceed GPU capabilities var maxTexturesUnits = _Capabilities["default"].getMaxTextureUnitsCount(); if (_this.defines.ORIENTED_IMAGES_COUNT > maxTexturesUnits) { console.warn("OrientedImageMaterial: Can't project ".concat(cameras.length, " textures, because it's more than GPU capabilities maximum texture units (").concat(maxTexturesUnits, ")")); // Clamp number of textures used _this.defines.ORIENTED_IMAGES_COUNT = maxTexturesUnits - 1; console.warn("OrientedImageMaterial: We'll use only the first ".concat(_this.defines.ORIENTED_IMAGES_COUNT, " cameras.")); } if (options.useBaseMaterial) { _this.defines.USE_BASE_MATERIAL = true; } _this.defines.USE_DISTORTION = Number(cameras.some(function (camera) { return camera.distortion.pps !== null; })); _this.alphaBorder = options.alphaBorder | 20; _this.defines.DEBUG_ALPHA_BORDER = options.debugAlphaBorder | 0; _this.cameras = cameras; var textureMatrix = []; var texture = []; var mask = []; var distortion = []; _this.group = new THREE.Group(); for (var i = 0; i < _this.defines.ORIENTED_IMAGES_COUNT; ++i) { texture[i] = noTexture; mask[i] = noMask; textureMatrix[i] = new THREE.Matrix4(); cameras[i].needsUpdate = true; distortion[i] = cameras[i].distortion; _this.group.add(cameras[i]); } _this.uniforms.opacity = new THREE.Uniform(_this.opacity); _this.uniforms.projectiveTextureAlphaBorder = new THREE.Uniform(_this.alphaBorder); _this.uniforms.projectiveTextureDistortion = new THREE.Uniform(distortion); _this.uniforms.projectiveTextureMatrix = new THREE.Uniform(textureMatrix); _this.uniforms.projectiveTexture = new THREE.Uniform(texture); _this.uniforms.mask = new THREE.Uniform(mask); _this.uniforms.boostLight = new THREE.Uniform(false); _this.uniforms.noProjectiveMaterial = new THREE.Uniform({ lightDirection: new THREE.Vector3(0.5, 0.5, -0.5), ambient: new THREE.Color(0.1, 0.1, 0.1), opacity: 0.75 }); if (_Capabilities["default"].isLogDepthBufferSupported()) { _this.defines.USE_LOGDEPTHBUF = 1; _this.defines.USE_LOGDEPTHBUF_EXT = 1; } _this.vertexShader = textureVS; _this.fragmentShader = _ShaderUtils["default"].unrollLoops(textureFS, _this.defines); return _this; } /** * Set new textures and new position/orientation of the camera set. * @param {THREE.Texture} textures - Array of [THREE.Texture]{@link https://threejs.org/docs/#api/en/textures/Texture}. * @param {Object} feature - New position / orientation of the set of cameras * @param {Array} camerasNames - camera names of panoramic feature * @param {THREE.Vector3} feature.position - New position. * @param {THREE.Quaternion} feature.quaternion - New orientation. */ (0, _createClass2["default"])(OrientedImageMaterial, [{ key: "setTextures", value: function setTextures(textures, feature, camerasNames) { var _this2 = this; if (!textures) { return; } this.group.position.copy(feature.position); this.group.quaternion.copy(feature.quaternion); var _loop = function (i) { _this2.uniforms.projectiveTexture.value[i].dispose(); _this2.uniforms.projectiveTexture.value[i] = textures[i]; // check camera changes if (camerasNames) { var currentCamera = _this2.group.children[i]; if (camerasNames[i] != currentCamera.name) { var camera = _this2.cameras.find(function (cam) { return cam.name === camerasNames[i]; }); _this2.uniforms.mask.value[i] = camera.maskTexture || noMask; _this2.uniforms.mask.value[i].needsUpdate = true; _this2.uniforms.projectiveTextureDistortion.value[i] = camera.distortion; _this2.group.children[i] = camera; camera.parent = _this2.group; } } _this2.group.children[i].needsUpdate = true; }; for (var i = 0; i < textures.length && i < this.defines.ORIENTED_IMAGES_COUNT; ++i) { _loop(i); } this.group.updateMatrixWorld(true); // update the matrixWorldInverse of the cameras } /** * Udate the uniforms using the current value of camera.matrixWorld. * Need to be called when the camera of the scene has changed. * @param {THREE.Camera} viewCamera - Camera of the scene. */ }, { key: "updateUniforms", value: function updateUniforms(viewCamera) { for (var i = 0; i < this.group.children.length; ++i) { var camera = this.group.children[i]; if (camera.needsUpdate) { camera.textureMatrixWorldInverse.multiplyMatrices(ndcToTextureMatrix, camera.projectionMatrix); camera.textureMatrixWorldInverse.multiply(camera.matrixWorldInverse); camera.needsUpdate = false; } this.uniforms.projectiveTextureMatrix.value[i].multiplyMatrices(camera.textureMatrixWorldInverse, viewCamera.matrixWorld); } } }]); return OrientedImageMaterial; }(THREE.RawShaderMaterial); var _default = OrientedImageMaterial; exports["default"] = _default;