GlobeSurfaceShaderSet.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*global define*/
  2. define([
  3. '../Core/defined',
  4. '../Core/destroyObject',
  5. '../Scene/SceneMode',
  6. '../Scene/terrainAttributeLocations'
  7. ], function(
  8. defined,
  9. destroyObject,
  10. SceneMode,
  11. terrainAttributeLocations) {
  12. "use strict";
  13. function GlobeSurfaceShader(numberOfDayTextures, flags, shaderProgram) {
  14. this.numberOfDayTextures = numberOfDayTextures;
  15. this.flags = flags;
  16. this.shaderProgram = shaderProgram;
  17. }
  18. /**
  19. * Manages the shaders used to shade the surface of a {@link Globe}.
  20. *
  21. * @alias GlobeSurfaceShaderSet
  22. * @private
  23. */
  24. function GlobeSurfaceShaderSet() {
  25. this.baseVertexShaderSource = undefined;
  26. this.baseFragmentShaderSource = undefined;
  27. this._attributeLocations = terrainAttributeLocations;
  28. this._shadersByTexturesFlags = [];
  29. }
  30. GlobeSurfaceShaderSet.prototype.getShaderProgram = function(context, sceneMode, surfaceTile, numberOfDayTextures, applyBrightness, applyContrast, applyHue, applySaturation, applyGamma, applyAlpha, showReflectiveOcean, showOceanWaves, enableLighting, hasVertexNormals, useWebMercatorProjection) {
  31. var flags = sceneMode |
  32. (applyBrightness << 2) |
  33. (applyContrast << 3) |
  34. (applyHue << 4) |
  35. (applySaturation << 5) |
  36. (applyGamma << 6) |
  37. (applyAlpha << 7) |
  38. (showReflectiveOcean << 8) |
  39. (showOceanWaves << 9) |
  40. (enableLighting << 10) |
  41. (hasVertexNormals << 11) |
  42. (useWebMercatorProjection << 12);
  43. var surfaceShader = surfaceTile.surfaceShader;
  44. if (defined(surfaceShader) &&
  45. surfaceShader.numberOfDayTextures === numberOfDayTextures &&
  46. surfaceShader.flags === flags) {
  47. return surfaceShader.shaderProgram;
  48. }
  49. // New tile, or tile changed number of textures or flags.
  50. var shadersByFlags = this._shadersByTexturesFlags[numberOfDayTextures];
  51. if (!defined(shadersByFlags)) {
  52. shadersByFlags = this._shadersByTexturesFlags[numberOfDayTextures] = [];
  53. }
  54. surfaceShader = shadersByFlags[flags];
  55. if (!defined(surfaceShader)) {
  56. // Cache miss - we've never seen this combination of numberOfDayTextures and flags before.
  57. var vs = this.baseVertexShaderSource.clone();
  58. var fs = this.baseFragmentShaderSource.clone();
  59. fs.defines.push('TEXTURE_UNITS ' + numberOfDayTextures);
  60. if (applyBrightness) {
  61. fs.defines.push('APPLY_BRIGHTNESS');
  62. }
  63. if (applyContrast) {
  64. fs.defines.push('APPLY_CONTRAST');
  65. }
  66. if (applyHue) {
  67. fs.defines.push('APPLY_HUE');
  68. }
  69. if (applySaturation) {
  70. fs.defines.push('APPLY_SATURATION');
  71. }
  72. if (applyGamma) {
  73. fs.defines.push('APPLY_GAMMA');
  74. }
  75. if (applyAlpha) {
  76. fs.defines.push('APPLY_ALPHA');
  77. }
  78. if (showReflectiveOcean) {
  79. fs.defines.push('SHOW_REFLECTIVE_OCEAN');
  80. vs.defines.push('SHOW_REFLECTIVE_OCEAN');
  81. }
  82. if (showOceanWaves) {
  83. fs.defines.push('SHOW_OCEAN_WAVES');
  84. }
  85. if (enableLighting) {
  86. if (hasVertexNormals) {
  87. vs.defines.push('ENABLE_VERTEX_LIGHTING');
  88. fs.defines.push('ENABLE_VERTEX_LIGHTING');
  89. } else {
  90. vs.defines.push('ENABLE_DAYNIGHT_SHADING');
  91. fs.defines.push('ENABLE_DAYNIGHT_SHADING');
  92. }
  93. }
  94. var computeDayColor = '\
  95. vec4 computeDayColor(vec4 initialColor, vec2 textureCoordinates)\n\
  96. {\n\
  97. vec4 color = initialColor;\n';
  98. for (var i = 0; i < numberOfDayTextures; ++i) {
  99. computeDayColor += '\
  100. color = sampleAndBlend(\n\
  101. color,\n\
  102. u_dayTextures[' + i + '],\n\
  103. textureCoordinates,\n\
  104. u_dayTextureTexCoordsRectangle[' + i + '],\n\
  105. u_dayTextureTranslationAndScale[' + i + '],\n\
  106. ' + (applyAlpha ? 'u_dayTextureAlpha[' + i + ']' : '1.0') + ',\n\
  107. ' + (applyBrightness ? 'u_dayTextureBrightness[' + i + ']' : '0.0') + ',\n\
  108. ' + (applyContrast ? 'u_dayTextureContrast[' + i + ']' : '0.0') + ',\n\
  109. ' + (applyHue ? 'u_dayTextureHue[' + i + ']' : '0.0') + ',\n\
  110. ' + (applySaturation ? 'u_dayTextureSaturation[' + i + ']' : '0.0') + ',\n\
  111. ' + (applyGamma ? 'u_dayTextureOneOverGamma[' + i + ']' : '0.0') + '\n\
  112. );\n';
  113. }
  114. computeDayColor += '\
  115. return color;\n\
  116. }';
  117. fs.sources.push(computeDayColor);
  118. var getPosition3DMode = 'vec4 getPosition(vec3 position3DWC) { return getPosition3DMode(position3DWC); }';
  119. var getPosition2DMode = 'vec4 getPosition(vec3 position3DWC) { return getPosition2DMode(position3DWC); }';
  120. var getPositionColumbusViewMode = 'vec4 getPosition(vec3 position3DWC) { return getPositionColumbusViewMode(position3DWC); }';
  121. var getPositionMorphingMode = 'vec4 getPosition(vec3 position3DWC) { return getPositionMorphingMode(position3DWC); }';
  122. var getPositionMode;
  123. switch (sceneMode) {
  124. case SceneMode.SCENE3D:
  125. getPositionMode = getPosition3DMode;
  126. break;
  127. case SceneMode.SCENE2D:
  128. getPositionMode = getPosition2DMode;
  129. break;
  130. case SceneMode.COLUMBUS_VIEW:
  131. getPositionMode = getPositionColumbusViewMode;
  132. break;
  133. case SceneMode.MORPHING:
  134. getPositionMode = getPositionMorphingMode;
  135. break;
  136. }
  137. vs.sources.push(getPositionMode);
  138. var get2DYPositionFractionGeographicProjection = 'float get2DYPositionFraction() { return get2DGeographicYPositionFraction(); }';
  139. var get2DYPositionFractionMercatorProjection = 'float get2DYPositionFraction() { return get2DMercatorYPositionFraction(); }';
  140. var get2DYPositionFraction;
  141. if (useWebMercatorProjection) {
  142. get2DYPositionFraction = get2DYPositionFractionMercatorProjection;
  143. } else {
  144. get2DYPositionFraction = get2DYPositionFractionGeographicProjection;
  145. }
  146. vs.sources.push(get2DYPositionFraction);
  147. var shader = context.createShaderProgram(vs, fs, this._attributeLocations);
  148. surfaceShader = shadersByFlags[flags] = new GlobeSurfaceShader(numberOfDayTextures, flags, shader);
  149. }
  150. surfaceTile.surfaceShader = surfaceShader;
  151. return surfaceShader.shaderProgram;
  152. };
  153. GlobeSurfaceShaderSet.prototype.destroy = function() {
  154. var shadersByTexturesFlags = this._shadersByTexturesFlags;
  155. for (var textureCount in shadersByTexturesFlags) {
  156. if (shadersByTexturesFlags.hasOwnProperty(textureCount)) {
  157. var shadersByFlags = shadersByTexturesFlags[textureCount];
  158. if (!defined(shadersByFlags)) {
  159. continue;
  160. }
  161. for (var flags in shadersByFlags) {
  162. if (shadersByFlags.hasOwnProperty(flags)) {
  163. var shader = shadersByFlags[flags];
  164. if (defined(shader)) {
  165. shader.shaderProgram.destroy();
  166. }
  167. }
  168. }
  169. }
  170. }
  171. return destroyObject(this);
  172. };
  173. return GlobeSurfaceShaderSet;
  174. });