UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

223 lines (188 loc) 18 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); 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 THREE = _interopRequireWildcard(require("three")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* babel-plugin-inline-import './Chunk/color_layers_pars_fragment.glsl' */ var color_layers_pars_fragment = "struct Layer {\n int textureOffset;\n int crs;\n int effect_type;\n float effect_parameter;\n float opacity;\n};\n\n#include <itowns/custom_header_colorLayer>\n\nuniform sampler2D colorTextures[NUM_FS_TEXTURES];\nuniform vec4 colorOffsetScales[NUM_FS_TEXTURES];\nuniform Layer colorLayers[NUM_FS_TEXTURES];\nuniform int colorTextureCount;\n\nvec3 uvs[NUM_CRS];\n\nfloat getBorderDistance(vec2 uv) {\n vec2 p2 = min(uv, 1. -uv);\n return min(p2.x, p2.y);\n}\n\nfloat tolerance = 0.99;\n\nvec4 applyWhiteToInvisibleEffect(vec4 color, float intensity) {\n float a = dot(color.rgb, vec3(0.333333333));\n if (a >= tolerance) {\n color.a *= 1.0 - pow(abs(a), intensity);\n }\n return color;\n}\n\nvec4 applyLightColorToInvisibleEffect(vec4 color, float intensity) {\n float a = max(0.05,1. - length(color.xyz - 1.));\n color.a *= 1.0 - pow(abs(a), intensity);\n color.rgb *= color.rgb * color.rgb;\n return color;\n}\n\n#if defined(DEBUG)\nuniform bool showOutline;\nuniform vec3 outlineColors[NUM_CRS];\nuniform float outlineWidth;\n\nvec4 getOutlineColor(vec3 outlineColor, vec2 uv) {\n float alpha = 1. - clamp(getBorderDistance(uv) / outlineWidth, 0., 1.);\n return vec4(outlineColor, alpha);\n}\n#endif\n\nuniform float minBorderDistance;\nvec4 getLayerColor(int textureOffset, sampler2D tex, vec4 offsetScale, Layer layer) {\n if ( textureOffset >= colorTextureCount ) return vec4(0);\n\n vec3 uv;\n // #pragma unroll_loop\n for ( int i = 0; i < NUM_CRS; i ++ ) {\n if ( i == layer.crs ) uv = uvs[ i ];\n }\n\n float borderDistance = getBorderDistance(uv.xy);\n if (textureOffset != layer.textureOffset + int(uv.z) || borderDistance < minBorderDistance ) return vec4(0);\n vec4 color = texture2D(tex, pitUV(uv.xy, offsetScale));\n if (layer.effect_type == 1) {\n color.rgb /= color.a;\n color = applyLightColorToInvisibleEffect(color, layer.effect_parameter);\n } else if (layer.effect_type == 2) {\n color.rgb /= color.a;\n color = applyWhiteToInvisibleEffect(color, layer.effect_parameter);\n } else if (layer.effect_type == 3) {\n #include <itowns/custom_body_colorLayer>\n }\n color.a *= layer.opacity;\n return color;\n}\n"; /* babel-plugin-inline-import './Chunk/elevation_pars_vertex.glsl' */ var elevation_pars_vertex = "#if NUM_VS_TEXTURES > 0\n struct Layer {\n float scale;\n float bias;\n int mode;\n float zmin;\n float zmax;\n };\n\n uniform Layer elevationLayers[NUM_VS_TEXTURES];\n uniform sampler2D elevationTextures[NUM_VS_TEXTURES];\n uniform vec4 elevationOffsetScales[NUM_VS_TEXTURES];\n uniform int elevationTextureCount;\n\n highp float decode32(highp vec4 rgba) {\n highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;\n highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;\n highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);\n highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));\n return Result;\n }\n\n float getElevationMode(vec2 uv, sampler2D tex, int mode) {\n if (mode == ELEVATION_RGBA)\n return decode32(texture2D( tex, uv ).abgr * 255.0);\n if (mode == ELEVATION_DATA || mode == ELEVATION_COLOR)\n #if defined(WEBGL2)\n return texture2D( tex, uv ).r;\n #else\n return texture2D( tex, uv ).w;\n #endif\n return 0.;\n }\n\n float getElevation(vec2 uv, sampler2D tex, vec4 offsetScale, Layer layer) {\n uv = uv * offsetScale.zw + offsetScale.xy;\n float d = getElevationMode(uv, tex, layer.mode);\n if (d < layer.zmin || d > layer.zmax) d = 0.;\n return d * layer.scale + layer.bias;\n }\n#endif\n"; /* babel-plugin-inline-import './Chunk/elevation_vertex.glsl' */ var elevation_vertex = "#if NUM_VS_TEXTURES > 0\n if(elevationTextureCount > 0) {\n float elevation = getElevation(uv, elevationTextures[0], elevationOffsetScales[0], elevationLayers[0]);\n transformed += elevation * normal;\n }\n#endif\n"; /* babel-plugin-inline-import './Chunk/fog_fragment.glsl' */ var fog_fragment = "#if defined(USE_FOG)\n float fogFactor = 1. - min( exp(-fogDepth / fogDistance), 1.);\n gl_FragColor.rgb = mix(gl_FragColor.rgb, fogColor, fogFactor);\n#endif\n"; /* babel-plugin-inline-import './Chunk/fog_pars_fragment.glsl' */ var fog_pars_fragment = "#if defined(USE_FOG)\nuniform vec3 fogColor;\nuniform float fogDistance;\nvarying float fogDepth;\n#endif\n"; /* babel-plugin-inline-import './Chunk/lighting_fragment.glsl' */ var lighting_fragment = "if (lightingEnabled) {\n float light = min(2. * dot(vNormal, lightPosition), 1.);\n gl_FragColor.rgb *= light;\n}\n"; /* babel-plugin-inline-import './Chunk/lighting_pars_fragment.glsl' */ var lighting_pars_fragment = "uniform bool lightingEnabled;\nuniform vec3 lightPosition;\nvarying vec3 vNormal;\n"; /* babel-plugin-inline-import './Chunk/mode_pars_fragment.glsl' */ var mode_pars_fragment = "#if MODE == MODE_ID || MODE == MODE_DEPTH\n#include <packing>\n#endif\n\n#if MODE == MODE_ID\nuniform int objectId;\n#endif\n"; /* babel-plugin-inline-import './Chunk/mode_depth_fragment.glsl' */ var mode_depth_fragment = "#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\ngl_FragColor = packDepthToRGBA(gl_FragDepthEXT);\n#else\nfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\ngl_FragColor = packDepthToRGBA(fragCoordZ);\n#endif"; /* babel-plugin-inline-import './Chunk/mode_id_fragment.glsl' */ var mode_id_fragment = "// 16777216.0 == 256.0 * 256.0 * 256.0\ngl_FragColor = packDepthToRGBA(float(objectId) / 16777216.0);\n"; /* babel-plugin-inline-import './Chunk/overlay_fragment.glsl' */ var overlay_fragment = "gl_FragColor.rgb = mix(gl_FragColor.rgb, overlayColor, overlayAlpha);\n"; /* babel-plugin-inline-import './Chunk/overlay_pars_fragment.glsl' */ var overlay_pars_fragment = "uniform vec3 overlayColor;\nuniform float overlayAlpha;\n"; /* babel-plugin-inline-import './Chunk/pitUV.glsl' */ var pitUV = "vec2 pitUV(vec2 uv, vec4 pit)\n{\n return uv * pit.zw + vec2(pit.x, 1.0 - pit.w - pit.y);\n}\n\n"; /* babel-plugin-inline-import './Chunk/precision_qualifier.glsl' */ var precision_qualifier = "precision highp float;\nprecision highp int;\n"; /* babel-plugin-inline-import './Chunk/project_pars_vertex.glsl' */ var project_pars_vertex = "attribute vec3 position;\nuniform mat4 projectionMatrix;\nuniform mat4 modelViewMatrix;\n"; /* babel-plugin-inline-import './Chunk/projective_texturing_vertex.glsl' */ var projective_texturing_vertex = "for(int i = 0; i < ORIENTED_IMAGES_COUNT; ++i)\n projectiveTextureCoords[i] = projectiveTextureMatrix[i] * mvPosition;\n"; /* babel-plugin-inline-import './Chunk/projective_texturing_pars_vertex.glsl' */ var projective_texturing_pars_vertex = "uniform mat4 projectiveTextureMatrix[ORIENTED_IMAGES_COUNT];\nvarying vec4 projectiveTextureCoords[ORIENTED_IMAGES_COUNT];\n"; /* babel-plugin-inline-import './Chunk/projective_texturing_pars_fragment.glsl' */ var projective_texturing_pars_fragment = "uniform sampler2D projectiveTexture[ORIENTED_IMAGES_COUNT];\nuniform sampler2D mask[ORIENTED_IMAGES_COUNT];\nvarying vec4 projectiveTextureCoords[ORIENTED_IMAGES_COUNT];\nuniform float projectiveTextureAlphaBorder;\nuniform float opacity;\nuniform bool boostLight;\n\nstruct Distortion {\n vec2 size;\n#if USE_DISTORTION\n vec2 pps;\n vec4 polynom;\n vec3 l1l2;\n#endif\n};\n\nuniform Distortion projectiveTextureDistortion[ORIENTED_IMAGES_COUNT];\n\nfloat getAlphaBorder(vec2 p)\n{\n vec2 d = clamp(projectiveTextureAlphaBorder * min(p, 1. - p), 0., 1.);\n return min(d.x, d.y);\n}\n\n#if USE_DISTORTION\nvoid distort(inout vec2 p, vec4 polynom, vec2 pps)\n{\n vec2 v = p - pps;\n float v2 = dot(v, v);\n if (v2 > polynom.w) {\n p = vec2(-1.);\n }\n else {\n p += (v2 * (polynom.x + v2 * (polynom.y + v2 * polynom.z) ) ) * v;\n }\n}\n\nvoid distort(inout vec2 p, vec4 polynom, vec3 l1l2, vec2 pps)\n{\n if ((l1l2.x == 0.) && (l1l2.y == 0.)) {\n distort(p, polynom, pps);\n } else {\n vec2 AB = (p - pps) / l1l2.z;\n float R = length(AB);\n float lambda = atan(R) / R;\n vec2 ab = lambda * AB;\n float rho2 = dot(ab, ab);\n float r357 = 1. + rho2* (polynom.x + rho2* (polynom.y + rho2 * polynom.z));\n p = pps + l1l2.z * (r357 * ab + vec2(dot(l1l2.xy, ab), l1l2.y * ab.x));\n }\n}\n#endif\n\nvec4 mixBaseColor(vec4 aColor, vec4 baseColor) {\n #ifdef USE_BASE_MATERIAL\n baseColor.rgb = aColor.a == 1.0 ? aColor.rgb : mix(baseColor, aColor, aColor.a).rgb;\n baseColor.a = min(1.0, aColor.a + baseColor.a);\n #else\n baseColor.rgb += aColor.rgb * aColor.a;\n baseColor.a += aColor.a;\n #endif\n return baseColor;\n}\n\nvec4 projectiveTextureColor(vec4 coords, Distortion distortion, sampler2D tex, sampler2D mask, vec4 baseColor) {\n vec3 p = coords.xyz / coords.w;\n if(p.z * p.z < 1.) {\n#if USE_DISTORTION\n p.xy *= distortion.size;\n distort(p.xy, distortion.polynom, distortion.l1l2, distortion.pps);\n p.xy /= distortion.size;\n#endif\n\n float d = getAlphaBorder(p.xy) * texture2D(mask, p.xy).r;\n\n if(d > 0.) {\n\n#if DEBUG_ALPHA_BORDER\n vec3 r = texture2D(tex, p.xy).rgb;\n return mixBaseColor(vec4( r.r * d, r.g, r.b, 1.0), baseColor);\n#else\n vec4 color = texture2D(tex, p.xy);\n color.a *= d;\n if (boostLight) {\n return mixBaseColor(vec4(sqrt(color.rgb), color.a), baseColor);\n } else {\n return mixBaseColor(color, baseColor);\n }\n#endif\n\n }\n }\n return mixBaseColor(vec4(0.), baseColor);\n}\n"; /* babel-plugin-inline-import './Chunk/WebGL2_pars_vertex.glsl' */ var WebGL2_pars_vertex = "// Copy from GLSL 3.0 conversion for built-in materials and ShaderMaterial in THREE.WebGLProgram\n// https://github.com/mrdoob/three.js/blob/696d7836d1fc56c4702a475e6991c4adef7357f4/src/renderers/webgl/WebGLProgram.js#L682\n#if defined(WEBGL2)\n#define attribute in\n#define varying out\n#define texture2D texture\n#endif\n"; /* babel-plugin-inline-import './Chunk/WebGL2_pars_fragment.glsl' */ var WebGL2_pars_fragment = "// Copy from GLSL 3.0 conversion for built-in materials and ShaderMaterial in THREE.WebGLProgram\n// https://github.com/mrdoob/three.js/blob/696d7836d1fc56c4702a475e6991c4adef7357f4/src/renderers/webgl/WebGLProgram.js#L682\n#if defined(WEBGL2)\n#define varying in\nout highp vec4 pc_fragColor;\n#define gl_FragColor pc_fragColor\n#define gl_FragDepthEXT gl_FragDepth\n#define texture2D texture\n#define textureCube texture\n#define texture2DProj textureProj\n#define texture2DLodEXT textureLod\n#define texture2DProjLodEXT textureProjLod\n#define textureCubeLodEXT textureLod\n#define texture2DGradEXT textureGrad\n#define texture2DProjGradEXT textureProjGrad\n#define textureCubeGradEXT textureGrad\n#endif\n"; var custom_header_colorLayer = '// no custom header'; var custom_body_colorLayer = '// no custom body'; var itownsShaderChunk = { color_layers_pars_fragment: color_layers_pars_fragment, custom_body_colorLayer: custom_body_colorLayer, custom_header_colorLayer: custom_header_colorLayer, elevation_pars_vertex: elevation_pars_vertex, elevation_vertex: elevation_vertex, fog_fragment: fog_fragment, fog_pars_fragment: fog_pars_fragment, lighting_fragment: lighting_fragment, lighting_pars_fragment: lighting_pars_fragment, mode_depth_fragment: mode_depth_fragment, mode_id_fragment: mode_id_fragment, mode_pars_fragment: mode_pars_fragment, overlay_fragment: overlay_fragment, overlay_pars_fragment: overlay_pars_fragment, pitUV: pitUV, precision_qualifier: precision_qualifier, projective_texturing_vertex: projective_texturing_vertex, projective_texturing_pars_vertex: projective_texturing_pars_vertex, projective_texturing_pars_fragment: projective_texturing_pars_fragment, project_pars_vertex: project_pars_vertex, WebGL2_pars_vertex: WebGL2_pars_vertex, WebGL2_pars_fragment: WebGL2_pars_fragment }; /** * The ShaderChunkManager manages the itowns chunks shader. * It adds chunks to THREE.ShaderChunk to compile shaders * * In itowns, if you want access to `ShaderChunkManager` instance : * * ```js * import ShaderChunk from 'Renderer/Shader/ShaderChunk'; * ``` * or * ```js * const ShaderChunk = itowns.ShaderChunk'; * ``` * * @property {Object} target - The target to install the chunks into. * @property {string} [path] - A path to add before a chunk name as a prefix. * */ var ShaderChunkManager = /*#__PURE__*/function () { /** * Constructs a new instance ShaderChunkManager. * * @constructor * * @param {Object} target - The target to install the chunks into. * @param {string} [path] - A path to add before a chunk name as a prefix. * */ function ShaderChunkManager(target, path) { (0, _classCallCheck2["default"])(this, ShaderChunkManager); this.path = path; this.target = target; this.install(); } /** * Set the header ColorLayer shader. * * @param {string} header The glsl header */ (0, _createClass2["default"])(ShaderChunkManager, [{ key: "customHeaderColorLayer", value: function customHeaderColorLayer(header) { itownsShaderChunk.custom_header_colorLayer = header; this.target["".concat(this.path, "custom_header_colorLayer")] = header; } /** * Set the body ColorLayer shader. * You could define you color terrain shader, with a header and a body. * the header defines yours fonctions and the body defines the process on ColorLayer. * @example <caption>Custom shader chunk</caption> * itowns.ShaderChunk.customHeaderColorLayer(` * // define yours methods * vec4 myColor(vec4 color, float a) { * return color * a; * } * `); * itowns.ShaderChunk.customBodyColorLayer(` * // the body set final color layer. * // layer.amount_effect is variable, it could be change in Layer instance. * color = myColor(color, layer.amount_effect) * `); * * var colorLayer = new itowns.ColorLayer('OPENSM', { * source, * type_effect: itowns.colorLayerEffects.customEffect, * amount_effect: 0.5, * }); * * @param {string} body The glsl body */ }, { key: "customBodyColorLayer", value: function customBodyColorLayer(body) { itownsShaderChunk.custom_body_colorLayer = body; this.target["".concat(this.path, "custom_body_colorLayer")] = body; } /** * Install chunks in a target, for example THREE.ShaderChunk, with adding an * optional path. * * @param {Object} target - The target to install the chunks into. * @param {Object} chunks - The chunks to install. The key of each chunk will be * the name of installation of the chunk in the target (plus an optional path). * @param {string} [path] - A path to add before a chunk name as a prefix. * * @return {Object} The target with installed chunks. */ }, { key: "install", value: function install() { var _this = this; var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.target; var chunks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : itownsShaderChunk; var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.path; Object.keys(chunks).forEach(function (key) { Object.defineProperty(_this, key, { get: function get() { return chunks[key]; } }); target[path + key] = chunks[key]; }); return target; } }]); return ShaderChunkManager; }(); var ShaderChunk = new ShaderChunkManager(THREE.ShaderChunk, 'itowns/'); var _default = ShaderChunk; exports["default"] = _default;