智慧水务管理系统 - 精河县供水工程综合管理平台

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. import defined from "../Core/defined.js";
  2. import destroyObject from "../Core/destroyObject.js";
  3. import TerrainQuantization from "../Core/TerrainQuantization.js";
  4. import ShaderProgram from "../Renderer/ShaderProgram.js";
  5. import getClippingFunction from "./getClippingFunction.js";
  6. import SceneMode from "./SceneMode.js";
  7. function GlobeSurfaceShader(
  8. numberOfDayTextures,
  9. flags,
  10. material,
  11. shaderProgram,
  12. clippingShaderState,
  13. clippingPolygonShaderState,
  14. ) {
  15. this.numberOfDayTextures = numberOfDayTextures;
  16. this.flags = flags;
  17. this.material = material;
  18. this.shaderProgram = shaderProgram;
  19. this.clippingShaderState = clippingShaderState;
  20. this.clippingPolygonShaderState = clippingPolygonShaderState;
  21. }
  22. /**
  23. * Manages the shaders used to shade the surface of a {@link Globe}.
  24. *
  25. * @alias GlobeSurfaceShaderSet
  26. * @private
  27. */
  28. function GlobeSurfaceShaderSet() {
  29. this.baseVertexShaderSource = undefined;
  30. this.baseFragmentShaderSource = undefined;
  31. this._shadersByTexturesFlags = [];
  32. this.material = undefined;
  33. }
  34. function getPositionMode(sceneMode) {
  35. const getPosition3DMode =
  36. "vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPosition3DMode(position, height, textureCoordinates); }";
  37. const getPositionColumbusViewAnd2DMode =
  38. "vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPositionColumbusViewMode(position, height, textureCoordinates); }";
  39. const getPositionMorphingMode =
  40. "vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPositionMorphingMode(position, height, textureCoordinates); }";
  41. let positionMode;
  42. switch (sceneMode) {
  43. case SceneMode.SCENE3D:
  44. positionMode = getPosition3DMode;
  45. break;
  46. case SceneMode.SCENE2D:
  47. case SceneMode.COLUMBUS_VIEW:
  48. positionMode = getPositionColumbusViewAnd2DMode;
  49. break;
  50. case SceneMode.MORPHING:
  51. positionMode = getPositionMorphingMode;
  52. break;
  53. }
  54. return positionMode;
  55. }
  56. function getPolygonClippingFunction(context) {
  57. // return a noop for webgl1
  58. if (!context.webgl2) {
  59. return `void clipPolygons(highp sampler2D clippingDistance, int regionsLength, vec2 clippingPosition, int regionIndex) {
  60. }`;
  61. }
  62. return `void clipPolygons(highp sampler2D clippingDistance, int regionsLength, vec2 clippingPosition, int regionIndex) {
  63. czm_clipPolygons(clippingDistance, regionsLength, clippingPosition, regionIndex);
  64. }`;
  65. }
  66. function getUnpackClippingFunction(context) {
  67. // return a noop for webgl1
  68. if (!context.webgl2) {
  69. return `vec4 unpackClippingExtents(highp sampler2D extentsTexture, int index) {
  70. return vec4();
  71. }`;
  72. }
  73. return `vec4 unpackClippingExtents(highp sampler2D extentsTexture, int index) {
  74. return czm_unpackClippingExtents(extentsTexture, index);
  75. }`;
  76. }
  77. function get2DYPositionFraction(useWebMercatorProjection) {
  78. const get2DYPositionFractionGeographicProjection =
  79. "float get2DYPositionFraction(vec2 textureCoordinates) { return get2DGeographicYPositionFraction(textureCoordinates); }";
  80. const get2DYPositionFractionMercatorProjection =
  81. "float get2DYPositionFraction(vec2 textureCoordinates) { return get2DMercatorYPositionFraction(textureCoordinates); }";
  82. return useWebMercatorProjection
  83. ? get2DYPositionFractionMercatorProjection
  84. : get2DYPositionFractionGeographicProjection;
  85. }
  86. GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
  87. const frameState = options.frameState;
  88. const surfaceTile = options.surfaceTile;
  89. const numberOfDayTextures = options.numberOfDayTextures;
  90. const applyBrightness = options.applyBrightness;
  91. const applyContrast = options.applyContrast;
  92. const applyHue = options.applyHue;
  93. const applySaturation = options.applySaturation;
  94. const applyGamma = options.applyGamma;
  95. const applyAlpha = options.applyAlpha;
  96. const applyDayNightAlpha = options.applyDayNightAlpha;
  97. const applySplit = options.applySplit;
  98. const hasWaterMask = options.hasWaterMask;
  99. const showReflectiveOcean = options.showReflectiveOcean;
  100. const showOceanWaves = options.showOceanWaves;
  101. const enableLighting = options.enableLighting;
  102. const dynamicAtmosphereLighting = options.dynamicAtmosphereLighting;
  103. const dynamicAtmosphereLightingFromSun =
  104. options.dynamicAtmosphereLightingFromSun;
  105. const showGroundAtmosphere = options.showGroundAtmosphere;
  106. const perFragmentGroundAtmosphere = options.perFragmentGroundAtmosphere;
  107. const hasVertexNormals = options.hasVertexNormals;
  108. const useWebMercatorProjection = options.useWebMercatorProjection;
  109. const enableFog = options.enableFog;
  110. const enableClippingPlanes = options.enableClippingPlanes;
  111. const clippingPlanes = options.clippingPlanes;
  112. const enableClippingPolygons = options.enableClippingPolygons;
  113. const clippingPolygons = options.clippingPolygons;
  114. const clippedByBoundaries = options.clippedByBoundaries;
  115. const hasImageryLayerCutout = options.hasImageryLayerCutout;
  116. const colorCorrect = options.colorCorrect;
  117. const highlightFillTile = options.highlightFillTile;
  118. const colorToAlpha = options.colorToAlpha;
  119. const hasGeodeticSurfaceNormals = options.hasGeodeticSurfaceNormals;
  120. const hasExaggeration = options.hasExaggeration;
  121. const showUndergroundColor = options.showUndergroundColor;
  122. const translucent = options.translucent;
  123. let quantization = 0;
  124. let quantizationDefine = "";
  125. const mesh = surfaceTile.renderedMesh;
  126. const terrainEncoding = mesh.encoding;
  127. const quantizationMode = terrainEncoding.quantization;
  128. if (quantizationMode === TerrainQuantization.BITS12) {
  129. quantization = 1;
  130. quantizationDefine = "QUANTIZATION_BITS12";
  131. }
  132. let cartographicLimitRectangleFlag = 0;
  133. let cartographicLimitRectangleDefine = "";
  134. if (clippedByBoundaries) {
  135. cartographicLimitRectangleFlag = 1;
  136. cartographicLimitRectangleDefine = "TILE_LIMIT_RECTANGLE";
  137. }
  138. let imageryCutoutFlag = 0;
  139. let imageryCutoutDefine = "";
  140. if (hasImageryLayerCutout) {
  141. imageryCutoutFlag = 1;
  142. imageryCutoutDefine = "APPLY_IMAGERY_CUTOUT";
  143. }
  144. const sceneMode = frameState.mode;
  145. // Bitwise OR uses 32-bit integers; bits 0-31 are packed below.
  146. // Flags beyond bit 31 use arithmetic to avoid silent wrap-around
  147. // (x << 32 === x << 0 in JavaScript).
  148. const flags =
  149. ((sceneMode |
  150. (applyBrightness << 2) |
  151. (applyContrast << 3) |
  152. (applyHue << 4) |
  153. (applySaturation << 5) |
  154. (applyGamma << 6) |
  155. (applyAlpha << 7) |
  156. (hasWaterMask << 8) |
  157. (showReflectiveOcean << 9) |
  158. (showOceanWaves << 10) |
  159. (enableLighting << 11) |
  160. (dynamicAtmosphereLighting << 12) |
  161. (dynamicAtmosphereLightingFromSun << 13) |
  162. (showGroundAtmosphere << 14) |
  163. (perFragmentGroundAtmosphere << 15) |
  164. (hasVertexNormals << 16) |
  165. (useWebMercatorProjection << 17) |
  166. (enableFog << 18) |
  167. (quantization << 19) |
  168. (applySplit << 20) |
  169. (enableClippingPlanes << 21) |
  170. (enableClippingPolygons << 22) |
  171. (cartographicLimitRectangleFlag << 23) |
  172. (imageryCutoutFlag << 24) |
  173. (colorCorrect << 25) |
  174. (highlightFillTile << 26) |
  175. (colorToAlpha << 27) |
  176. (hasGeodeticSurfaceNormals << 28) |
  177. (hasExaggeration << 29) |
  178. (showUndergroundColor << 30) |
  179. (translucent << 31)) >>>
  180. 0) +
  181. (applyDayNightAlpha ? 0x100000000 : 0);
  182. let currentClippingShaderState = 0;
  183. if (defined(clippingPlanes) && clippingPlanes.length > 0) {
  184. currentClippingShaderState = enableClippingPlanes
  185. ? clippingPlanes.clippingPlanesState
  186. : 0;
  187. }
  188. let currentClippingPolygonsShaderState = 0;
  189. if (defined(clippingPolygons) && clippingPolygons.length > 0) {
  190. currentClippingPolygonsShaderState = enableClippingPolygons
  191. ? clippingPolygons.clippingPolygonsState
  192. : 0;
  193. }
  194. let surfaceShader = surfaceTile.surfaceShader;
  195. if (
  196. defined(surfaceShader) &&
  197. surfaceShader.numberOfDayTextures === numberOfDayTextures &&
  198. surfaceShader.flags === flags &&
  199. surfaceShader.material === this.material &&
  200. surfaceShader.clippingShaderState === currentClippingShaderState &&
  201. surfaceShader.clippingPolygonShaderState ===
  202. currentClippingPolygonsShaderState
  203. ) {
  204. return surfaceShader.shaderProgram;
  205. }
  206. // New tile, or tile changed number of textures, flags, or clipping planes
  207. let shadersByFlags = this._shadersByTexturesFlags[numberOfDayTextures];
  208. if (!defined(shadersByFlags)) {
  209. shadersByFlags = this._shadersByTexturesFlags[numberOfDayTextures] = [];
  210. }
  211. surfaceShader = shadersByFlags[flags];
  212. if (
  213. !defined(surfaceShader) ||
  214. surfaceShader.material !== this.material ||
  215. surfaceShader.clippingShaderState !== currentClippingShaderState ||
  216. surfaceShader.clippingPolygonShaderState !==
  217. currentClippingPolygonsShaderState
  218. ) {
  219. // Cache miss - we've never seen this combination of numberOfDayTextures and flags before.
  220. const vs = this.baseVertexShaderSource.clone();
  221. const fs = this.baseFragmentShaderSource.clone();
  222. // Need to go before GlobeFS
  223. if (currentClippingShaderState !== 0) {
  224. fs.sources.unshift(
  225. getClippingFunction(clippingPlanes, frameState.context),
  226. );
  227. }
  228. // Need to go before GlobeFS
  229. if (currentClippingPolygonsShaderState !== 0) {
  230. fs.sources.unshift(getPolygonClippingFunction(frameState.context));
  231. vs.sources.unshift(getUnpackClippingFunction(frameState.context));
  232. }
  233. vs.defines.push(quantizationDefine);
  234. fs.defines.push(
  235. `TEXTURE_UNITS ${numberOfDayTextures}`,
  236. cartographicLimitRectangleDefine,
  237. imageryCutoutDefine,
  238. );
  239. if (applyBrightness) {
  240. fs.defines.push("APPLY_BRIGHTNESS");
  241. }
  242. if (applyContrast) {
  243. fs.defines.push("APPLY_CONTRAST");
  244. }
  245. if (applyHue) {
  246. fs.defines.push("APPLY_HUE");
  247. }
  248. if (applySaturation) {
  249. fs.defines.push("APPLY_SATURATION");
  250. }
  251. if (applyGamma) {
  252. fs.defines.push("APPLY_GAMMA");
  253. }
  254. if (applyAlpha) {
  255. fs.defines.push("APPLY_ALPHA");
  256. }
  257. if (applyDayNightAlpha) {
  258. fs.defines.push("APPLY_DAY_NIGHT_ALPHA");
  259. }
  260. if (hasWaterMask) {
  261. fs.defines.push("HAS_WATER_MASK");
  262. }
  263. if (showReflectiveOcean) {
  264. fs.defines.push("SHOW_REFLECTIVE_OCEAN");
  265. vs.defines.push("SHOW_REFLECTIVE_OCEAN");
  266. }
  267. if (showOceanWaves) {
  268. fs.defines.push("SHOW_OCEAN_WAVES");
  269. }
  270. if (colorToAlpha) {
  271. fs.defines.push("APPLY_COLOR_TO_ALPHA");
  272. }
  273. if (showUndergroundColor) {
  274. vs.defines.push("UNDERGROUND_COLOR");
  275. fs.defines.push("UNDERGROUND_COLOR");
  276. }
  277. if (translucent) {
  278. vs.defines.push("TRANSLUCENT");
  279. fs.defines.push("TRANSLUCENT");
  280. }
  281. if (enableLighting) {
  282. if (hasVertexNormals) {
  283. vs.defines.push("ENABLE_VERTEX_LIGHTING");
  284. fs.defines.push("ENABLE_VERTEX_LIGHTING");
  285. } else {
  286. vs.defines.push("ENABLE_DAYNIGHT_SHADING");
  287. fs.defines.push("ENABLE_DAYNIGHT_SHADING");
  288. }
  289. }
  290. if (dynamicAtmosphereLighting) {
  291. vs.defines.push("DYNAMIC_ATMOSPHERE_LIGHTING");
  292. fs.defines.push("DYNAMIC_ATMOSPHERE_LIGHTING");
  293. if (dynamicAtmosphereLightingFromSun) {
  294. vs.defines.push("DYNAMIC_ATMOSPHERE_LIGHTING_FROM_SUN");
  295. fs.defines.push("DYNAMIC_ATMOSPHERE_LIGHTING_FROM_SUN");
  296. }
  297. }
  298. if (showGroundAtmosphere) {
  299. vs.defines.push("GROUND_ATMOSPHERE");
  300. fs.defines.push("GROUND_ATMOSPHERE");
  301. if (perFragmentGroundAtmosphere) {
  302. vs.defines.push("PER_FRAGMENT_GROUND_ATMOSPHERE");
  303. fs.defines.push("PER_FRAGMENT_GROUND_ATMOSPHERE");
  304. }
  305. }
  306. vs.defines.push("INCLUDE_WEB_MERCATOR_Y");
  307. fs.defines.push("INCLUDE_WEB_MERCATOR_Y");
  308. if (enableFog) {
  309. vs.defines.push("FOG");
  310. fs.defines.push("FOG");
  311. }
  312. if (applySplit) {
  313. fs.defines.push("APPLY_SPLIT");
  314. }
  315. if (enableClippingPlanes) {
  316. fs.defines.push("ENABLE_CLIPPING_PLANES");
  317. }
  318. if (enableClippingPolygons) {
  319. fs.defines.push("ENABLE_CLIPPING_POLYGONS");
  320. vs.defines.push("ENABLE_CLIPPING_POLYGONS");
  321. if (clippingPolygons.inverse) {
  322. fs.defines.push("CLIPPING_INVERSE");
  323. }
  324. fs.defines.push(
  325. `CLIPPING_POLYGON_REGIONS_LENGTH ${clippingPolygons.extentsCount}`,
  326. );
  327. vs.defines.push(
  328. `CLIPPING_POLYGON_REGIONS_LENGTH ${clippingPolygons.extentsCount}`,
  329. );
  330. }
  331. if (colorCorrect) {
  332. fs.defines.push("COLOR_CORRECT");
  333. }
  334. if (highlightFillTile) {
  335. fs.defines.push("HIGHLIGHT_FILL_TILE");
  336. }
  337. if (hasGeodeticSurfaceNormals) {
  338. vs.defines.push("GEODETIC_SURFACE_NORMALS");
  339. }
  340. if (hasExaggeration) {
  341. vs.defines.push("EXAGGERATION");
  342. }
  343. let computeDayColor =
  344. "\
  345. vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates, float nightBlend)\n\
  346. {\n\
  347. vec4 color = initialColor;\n";
  348. if (hasImageryLayerCutout) {
  349. computeDayColor +=
  350. "\
  351. vec4 cutoutAndColorResult;\n\
  352. bool texelUnclipped;\n";
  353. }
  354. for (let i = 0; i < numberOfDayTextures; ++i) {
  355. if (hasImageryLayerCutout) {
  356. computeDayColor += `\
  357. cutoutAndColorResult = u_dayTextureCutoutRectangles[${i}];\n\
  358. texelUnclipped = v_textureCoordinates.x < cutoutAndColorResult.x || cutoutAndColorResult.z < v_textureCoordinates.x || v_textureCoordinates.y < cutoutAndColorResult.y || cutoutAndColorResult.w < v_textureCoordinates.y;\n\
  359. cutoutAndColorResult = sampleAndBlend(\n`;
  360. } else {
  361. computeDayColor +=
  362. "\
  363. color = sampleAndBlend(\n";
  364. }
  365. computeDayColor += `\
  366. color,\n\
  367. u_dayTextures[${i}],\n\
  368. u_dayTextureUseWebMercatorT[${i}] ? textureCoordinates.xz : textureCoordinates.xy,\n\
  369. u_dayTextureTexCoordsRectangle[${i}],\n\
  370. u_dayTextureTranslationAndScale[${i}],\n\
  371. ${applyAlpha ? `u_dayTextureAlpha[${i}]` : "1.0"},\n\
  372. ${applyDayNightAlpha ? `u_dayTextureNightAlpha[${i}]` : "1.0"},\n\
  373. ${applyDayNightAlpha ? `u_dayTextureDayAlpha[${i}]` : "1.0"},\n\
  374. ${applyBrightness ? `u_dayTextureBrightness[${i}]` : "0.0"},\n\
  375. ${applyContrast ? `u_dayTextureContrast[${i}]` : "0.0"},\n\
  376. ${applyHue ? `u_dayTextureHue[${i}]` : "0.0"},\n\
  377. ${applySaturation ? `u_dayTextureSaturation[${i}]` : "0.0"},\n\
  378. ${applyGamma ? `u_dayTextureOneOverGamma[${i}]` : "0.0"},\n\
  379. ${applySplit ? `u_dayTextureSplit[${i}]` : "0.0"},\n\
  380. ${colorToAlpha ? `u_colorsToAlpha[${i}]` : "vec4(0.0)"},\n\
  381. nightBlend\);\n`;
  382. if (hasImageryLayerCutout) {
  383. computeDayColor +=
  384. "\
  385. color = czm_branchFreeTernary(texelUnclipped, cutoutAndColorResult, color);\n";
  386. }
  387. }
  388. computeDayColor +=
  389. "\
  390. return color;\n\
  391. }";
  392. fs.sources.push(computeDayColor);
  393. vs.sources.push(getPositionMode(sceneMode));
  394. vs.sources.push(get2DYPositionFraction(useWebMercatorProjection));
  395. const shader = ShaderProgram.fromCache({
  396. context: frameState.context,
  397. vertexShaderSource: vs,
  398. fragmentShaderSource: fs,
  399. attributeLocations: terrainEncoding.getAttributeLocations(),
  400. });
  401. surfaceShader = shadersByFlags[flags] = new GlobeSurfaceShader(
  402. numberOfDayTextures,
  403. flags,
  404. this.material,
  405. shader,
  406. currentClippingShaderState,
  407. currentClippingPolygonsShaderState,
  408. );
  409. }
  410. surfaceTile.surfaceShader = surfaceShader;
  411. return surfaceShader.shaderProgram;
  412. };
  413. GlobeSurfaceShaderSet.prototype.destroy = function () {
  414. let flags;
  415. let shader;
  416. const shadersByTexturesFlags = this._shadersByTexturesFlags;
  417. for (const textureCount in shadersByTexturesFlags) {
  418. if (shadersByTexturesFlags.hasOwnProperty(textureCount)) {
  419. const shadersByFlags = shadersByTexturesFlags[textureCount];
  420. if (!defined(shadersByFlags)) {
  421. continue;
  422. }
  423. for (flags in shadersByFlags) {
  424. if (shadersByFlags.hasOwnProperty(flags)) {
  425. shader = shadersByFlags[flags];
  426. if (defined(shader)) {
  427. shader.shaderProgram.destroy();
  428. }
  429. }
  430. }
  431. }
  432. }
  433. return destroyObject(this);
  434. };
  435. export default GlobeSurfaceShaderSet;