itowns
Version:
A JS/WebGL framework for 3D geospatial data visualization
238 lines (192 loc) • 12.6 kB
JavaScript
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;
;