| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 | import defined from "../Core/defined.js";import destroyObject from "../Core/destroyObject.js";import TerrainQuantization from "../Core/TerrainQuantization.js";import ShaderProgram from "../Renderer/ShaderProgram.js";import getClippingFunction from "./getClippingFunction.js";import SceneMode from "./SceneMode.js";function GlobeSurfaceShader(  numberOfDayTextures,  flags,  material,  shaderProgram,  clippingShaderState) {  this.numberOfDayTextures = numberOfDayTextures;  this.flags = flags;  this.material = material;  this.shaderProgram = shaderProgram;  this.clippingShaderState = clippingShaderState;}/** * Manages the shaders used to shade the surface of a {@link Globe}. * * @alias GlobeSurfaceShaderSet * @private */function GlobeSurfaceShaderSet() {  this.baseVertexShaderSource = undefined;  this.baseFragmentShaderSource = undefined;  this._shadersByTexturesFlags = [];  this.material = undefined;}function getPositionMode(sceneMode) {  const getPosition3DMode =    "vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPosition3DMode(position, height, textureCoordinates); }";  const getPositionColumbusViewAnd2DMode =    "vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPositionColumbusViewMode(position, height, textureCoordinates); }";  const getPositionMorphingMode =    "vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPositionMorphingMode(position, height, textureCoordinates); }";  let positionMode;  switch (sceneMode) {    case SceneMode.SCENE3D:      positionMode = getPosition3DMode;      break;    case SceneMode.SCENE2D:    case SceneMode.COLUMBUS_VIEW:      positionMode = getPositionColumbusViewAnd2DMode;      break;    case SceneMode.MORPHING:      positionMode = getPositionMorphingMode;      break;  }  return positionMode;}function get2DYPositionFraction(useWebMercatorProjection) {  const get2DYPositionFractionGeographicProjection =    "float get2DYPositionFraction(vec2 textureCoordinates) { return get2DGeographicYPositionFraction(textureCoordinates); }";  const get2DYPositionFractionMercatorProjection =    "float get2DYPositionFraction(vec2 textureCoordinates) { return get2DMercatorYPositionFraction(textureCoordinates); }";  return useWebMercatorProjection    ? get2DYPositionFractionMercatorProjection    : get2DYPositionFractionGeographicProjection;}GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {  const frameState = options.frameState;  const surfaceTile = options.surfaceTile;  const numberOfDayTextures = options.numberOfDayTextures;  const applyBrightness = options.applyBrightness;  const applyContrast = options.applyContrast;  const applyHue = options.applyHue;  const applySaturation = options.applySaturation;  const applyGamma = options.applyGamma;  const applyAlpha = options.applyAlpha;  const applyDayNightAlpha = options.applyDayNightAlpha;  const applySplit = options.applySplit;  const showReflectiveOcean = options.showReflectiveOcean;  const showOceanWaves = options.showOceanWaves;  const enableLighting = options.enableLighting;  const dynamicAtmosphereLighting = options.dynamicAtmosphereLighting;  const dynamicAtmosphereLightingFromSun =    options.dynamicAtmosphereLightingFromSun;  const showGroundAtmosphere = options.showGroundAtmosphere;  const perFragmentGroundAtmosphere = options.perFragmentGroundAtmosphere;  const hasVertexNormals = options.hasVertexNormals;  const useWebMercatorProjection = options.useWebMercatorProjection;  const enableFog = options.enableFog;  const enableClippingPlanes = options.enableClippingPlanes;  const clippingPlanes = options.clippingPlanes;  const clippedByBoundaries = options.clippedByBoundaries;  const hasImageryLayerCutout = options.hasImageryLayerCutout;  const colorCorrect = options.colorCorrect;  const highlightFillTile = options.highlightFillTile;  const colorToAlpha = options.colorToAlpha;  const hasGeodeticSurfaceNormals = options.hasGeodeticSurfaceNormals;  const hasExaggeration = options.hasExaggeration;  const showUndergroundColor = options.showUndergroundColor;  const translucent = options.translucent;  let quantization = 0;  let quantizationDefine = "";  const mesh = surfaceTile.renderedMesh;  const terrainEncoding = mesh.encoding;  const quantizationMode = terrainEncoding.quantization;  if (quantizationMode === TerrainQuantization.BITS12) {    quantization = 1;    quantizationDefine = "QUANTIZATION_BITS12";  }  let cartographicLimitRectangleFlag = 0;  let cartographicLimitRectangleDefine = "";  if (clippedByBoundaries) {    cartographicLimitRectangleFlag = 1;    cartographicLimitRectangleDefine = "TILE_LIMIT_RECTANGLE";  }  let imageryCutoutFlag = 0;  let imageryCutoutDefine = "";  if (hasImageryLayerCutout) {    imageryCutoutFlag = 1;    imageryCutoutDefine = "APPLY_IMAGERY_CUTOUT";  }  const sceneMode = frameState.mode;  const flags =    sceneMode |    (applyBrightness << 2) |    (applyContrast << 3) |    (applyHue << 4) |    (applySaturation << 5) |    (applyGamma << 6) |    (applyAlpha << 7) |    (showReflectiveOcean << 8) |    (showOceanWaves << 9) |    (enableLighting << 10) |    (dynamicAtmosphereLighting << 11) |    (dynamicAtmosphereLightingFromSun << 12) |    (showGroundAtmosphere << 13) |    (perFragmentGroundAtmosphere << 14) |    (hasVertexNormals << 15) |    (useWebMercatorProjection << 16) |    (enableFog << 17) |    (quantization << 18) |    (applySplit << 19) |    (enableClippingPlanes << 20) |    (cartographicLimitRectangleFlag << 21) |    (imageryCutoutFlag << 22) |    (colorCorrect << 23) |    (highlightFillTile << 24) |    (colorToAlpha << 25) |    (hasGeodeticSurfaceNormals << 26) |    (hasExaggeration << 27) |    (showUndergroundColor << 28) |    (translucent << 29) |    (applyDayNightAlpha << 30);  let currentClippingShaderState = 0;  if (defined(clippingPlanes) && clippingPlanes.length > 0) {    currentClippingShaderState = enableClippingPlanes      ? clippingPlanes.clippingPlanesState      : 0;  }  let surfaceShader = surfaceTile.surfaceShader;  if (    defined(surfaceShader) &&    surfaceShader.numberOfDayTextures === numberOfDayTextures &&    surfaceShader.flags === flags &&    surfaceShader.material === this.material &&    surfaceShader.clippingShaderState === currentClippingShaderState  ) {    return surfaceShader.shaderProgram;  }  // New tile, or tile changed number of textures, flags, or clipping planes  let shadersByFlags = this._shadersByTexturesFlags[numberOfDayTextures];  if (!defined(shadersByFlags)) {    shadersByFlags = this._shadersByTexturesFlags[numberOfDayTextures] = [];  }  surfaceShader = shadersByFlags[flags];  if (    !defined(surfaceShader) ||    surfaceShader.material !== this.material ||    surfaceShader.clippingShaderState !== currentClippingShaderState  ) {    // Cache miss - we've never seen this combination of numberOfDayTextures and flags before.    const vs = this.baseVertexShaderSource.clone();    const fs = this.baseFragmentShaderSource.clone();    if (currentClippingShaderState !== 0) {      fs.sources.unshift(        getClippingFunction(clippingPlanes, frameState.context)      ); // Need to go before GlobeFS    }    vs.defines.push(quantizationDefine);    fs.defines.push(      `TEXTURE_UNITS ${numberOfDayTextures}`,      cartographicLimitRectangleDefine,      imageryCutoutDefine    );    if (applyBrightness) {      fs.defines.push("APPLY_BRIGHTNESS");    }    if (applyContrast) {      fs.defines.push("APPLY_CONTRAST");    }    if (applyHue) {      fs.defines.push("APPLY_HUE");    }    if (applySaturation) {      fs.defines.push("APPLY_SATURATION");    }    if (applyGamma) {      fs.defines.push("APPLY_GAMMA");    }    if (applyAlpha) {      fs.defines.push("APPLY_ALPHA");    }    if (applyDayNightAlpha) {      fs.defines.push("APPLY_DAY_NIGHT_ALPHA");    }    if (showReflectiveOcean) {      fs.defines.push("SHOW_REFLECTIVE_OCEAN");      vs.defines.push("SHOW_REFLECTIVE_OCEAN");    }    if (showOceanWaves) {      fs.defines.push("SHOW_OCEAN_WAVES");    }    if (colorToAlpha) {      fs.defines.push("APPLY_COLOR_TO_ALPHA");    }    if (showUndergroundColor) {      vs.defines.push("UNDERGROUND_COLOR");      fs.defines.push("UNDERGROUND_COLOR");    }    if (translucent) {      vs.defines.push("TRANSLUCENT");      fs.defines.push("TRANSLUCENT");    }    if (enableLighting) {      if (hasVertexNormals) {        vs.defines.push("ENABLE_VERTEX_LIGHTING");        fs.defines.push("ENABLE_VERTEX_LIGHTING");      } else {        vs.defines.push("ENABLE_DAYNIGHT_SHADING");        fs.defines.push("ENABLE_DAYNIGHT_SHADING");      }    }    if (dynamicAtmosphereLighting) {      vs.defines.push("DYNAMIC_ATMOSPHERE_LIGHTING");      fs.defines.push("DYNAMIC_ATMOSPHERE_LIGHTING");      if (dynamicAtmosphereLightingFromSun) {        vs.defines.push("DYNAMIC_ATMOSPHERE_LIGHTING_FROM_SUN");        fs.defines.push("DYNAMIC_ATMOSPHERE_LIGHTING_FROM_SUN");      }    }    if (showGroundAtmosphere) {      vs.defines.push("GROUND_ATMOSPHERE");      fs.defines.push("GROUND_ATMOSPHERE");      if (perFragmentGroundAtmosphere) {        vs.defines.push("PER_FRAGMENT_GROUND_ATMOSPHERE");        fs.defines.push("PER_FRAGMENT_GROUND_ATMOSPHERE");      }    }    vs.defines.push("INCLUDE_WEB_MERCATOR_Y");    fs.defines.push("INCLUDE_WEB_MERCATOR_Y");    if (enableFog) {      vs.defines.push("FOG");      fs.defines.push("FOG");    }    if (applySplit) {      fs.defines.push("APPLY_SPLIT");    }    if (enableClippingPlanes) {      fs.defines.push("ENABLE_CLIPPING_PLANES");    }    if (colorCorrect) {      fs.defines.push("COLOR_CORRECT");    }    if (highlightFillTile) {      fs.defines.push("HIGHLIGHT_FILL_TILE");    }    if (hasGeodeticSurfaceNormals) {      vs.defines.push("GEODETIC_SURFACE_NORMALS");    }    if (hasExaggeration) {      vs.defines.push("EXAGGERATION");    }    let computeDayColor =      "\    vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates, float nightBlend)\n\    {\n\        vec4 color = initialColor;\n";    if (hasImageryLayerCutout) {      computeDayColor +=        "\        vec4 cutoutAndColorResult;\n\        bool texelUnclipped;\n";    }    for (let i = 0; i < numberOfDayTextures; ++i) {      if (hasImageryLayerCutout) {        computeDayColor += `\        cutoutAndColorResult = u_dayTextureCutoutRectangles[${i}];\n\        texelUnclipped = v_textureCoordinates.x < cutoutAndColorResult.x || cutoutAndColorResult.z < v_textureCoordinates.x || v_textureCoordinates.y < cutoutAndColorResult.y || cutoutAndColorResult.w < v_textureCoordinates.y;\n\        cutoutAndColorResult = sampleAndBlend(\n`;      } else {        computeDayColor += "\        color = sampleAndBlend(\n";      }      computeDayColor += `\            color,\n\            u_dayTextures[${i}],\n\            u_dayTextureUseWebMercatorT[${i}] ? textureCoordinates.xz : textureCoordinates.xy,\n\            u_dayTextureTexCoordsRectangle[${i}],\n\            u_dayTextureTranslationAndScale[${i}],\n\            ${applyAlpha ? `u_dayTextureAlpha[${i}]` : "1.0"},\n\            ${applyDayNightAlpha ? `u_dayTextureNightAlpha[${i}]` : "1.0"},\n${        applyDayNightAlpha ? `u_dayTextureDayAlpha[${i}]` : "1.0"      },\n${applyBrightness ? `u_dayTextureBrightness[${i}]` : "0.0"},\n\            ${applyContrast ? `u_dayTextureContrast[${i}]` : "0.0"},\n\            ${applyHue ? `u_dayTextureHue[${i}]` : "0.0"},\n\            ${applySaturation ? `u_dayTextureSaturation[${i}]` : "0.0"},\n\            ${applyGamma ? `u_dayTextureOneOverGamma[${i}]` : "0.0"},\n\            ${applySplit ? `u_dayTextureSplit[${i}]` : "0.0"},\n\            ${colorToAlpha ? `u_colorsToAlpha[${i}]` : "vec4(0.0)"},\n\        nightBlend\        );\n`;      if (hasImageryLayerCutout) {        computeDayColor +=          "\        color = czm_branchFreeTernary(texelUnclipped, cutoutAndColorResult, color);\n";      }    }    computeDayColor += "\        return color;\n\    }";    fs.sources.push(computeDayColor);    vs.sources.push(getPositionMode(sceneMode));    vs.sources.push(get2DYPositionFraction(useWebMercatorProjection));    const shader = ShaderProgram.fromCache({      context: frameState.context,      vertexShaderSource: vs,      fragmentShaderSource: fs,      attributeLocations: terrainEncoding.getAttributeLocations(),    });    surfaceShader = shadersByFlags[flags] = new GlobeSurfaceShader(      numberOfDayTextures,      flags,      this.material,      shader,      currentClippingShaderState    );  }  surfaceTile.surfaceShader = surfaceShader;  return surfaceShader.shaderProgram;};GlobeSurfaceShaderSet.prototype.destroy = function () {  let flags;  let shader;  const shadersByTexturesFlags = this._shadersByTexturesFlags;  for (const textureCount in shadersByTexturesFlags) {    if (shadersByTexturesFlags.hasOwnProperty(textureCount)) {      const shadersByFlags = shadersByTexturesFlags[textureCount];      if (!defined(shadersByFlags)) {        continue;      }      for (flags in shadersByFlags) {        if (shadersByFlags.hasOwnProperty(flags)) {          shader = shadersByFlags[flags];          if (defined(shader)) {            shader.shaderProgram.destroy();          }        }      }    }  }  return destroyObject(this);};export default GlobeSurfaceShaderSet;
 |