| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117 | import combine from "../Core/combine.js";import defaultValue from "../Core/defaultValue.js";import defined from "../Core/defined.js";import NearFarScalar from "../Core/NearFarScalar.js";import Rectangle from "../Core/Rectangle.js";import DrawCommand from "../Renderer/DrawCommand.js";import Pass from "../Renderer/Pass.js";import RenderState from "../Renderer/RenderState.js";import ShaderSource from "../Renderer/ShaderSource.js";import BlendingState from "./BlendingState.js";import CullFace from "./CullFace.js";import SceneMode from "./SceneMode.js";const DerivedCommandType = {  OPAQUE_FRONT_FACE: 0,  OPAQUE_BACK_FACE: 1,  DEPTH_ONLY_FRONT_FACE: 2,  DEPTH_ONLY_BACK_FACE: 3,  DEPTH_ONLY_FRONT_AND_BACK_FACE: 4,  TRANSLUCENT_FRONT_FACE: 5,  TRANSLUCENT_BACK_FACE: 6,  TRANSLUCENT_FRONT_FACE_MANUAL_DEPTH_TEST: 7,  TRANSLUCENT_BACK_FACE_MANUAL_DEPTH_TEST: 8,  PICK_FRONT_FACE: 9,  PICK_BACK_FACE: 10,  DERIVED_COMMANDS_MAXIMUM_LENGTH: 11,};const derivedCommandsMaximumLength =  DerivedCommandType.DERIVED_COMMANDS_MAXIMUM_LENGTH;const DerivedCommandNames = [  "opaqueFrontFaceCommand",  "opaqueBackFaceCommand",  "depthOnlyFrontFaceCommand",  "depthOnlyBackFaceCommand",  "depthOnlyFrontAndBackFaceCommand",  "translucentFrontFaceCommand",  "translucentBackFaceCommand",  "translucentFrontFaceManualDepthTestCommand",  "translucentBackFaceManualDepthTestCommand",  "pickFrontFaceCommand",  "pickBackFaceCommand",];/** * @private */function GlobeTranslucencyState() {  this._frontFaceAlphaByDistance = new NearFarScalar(0.0, 1.0, 0.0, 1.0);  this._backFaceAlphaByDistance = new NearFarScalar(0.0, 1.0, 0.0, 1.0);  this._frontFaceTranslucent = false;  this._backFaceTranslucent = false;  this._requiresManualDepthTest = false;  this._sunVisibleThroughGlobe = false;  this._environmentVisible = false;  this._useDepthPlane = false;  this._numberOfTextureUniforms = 0;  this._globeTranslucencyFramebuffer = undefined;  this._rectangle = Rectangle.clone(Rectangle.MAX_VALUE);  this._derivedCommandKey = 0;  this._derivedCommandsDirty = false;  this._derivedCommandPacks = undefined;  this._derivedCommandTypes = new Array(derivedCommandsMaximumLength);  this._derivedBlendCommandTypes = new Array(derivedCommandsMaximumLength);  this._derivedPickCommandTypes = new Array(derivedCommandsMaximumLength);  this._derivedCommandTypesToUpdate = new Array(derivedCommandsMaximumLength);  this._derivedCommandsLength = 0;  this._derivedBlendCommandsLength = 0;  this._derivedPickCommandsLength = 0;  this._derivedCommandsToUpdateLength = 0;}Object.defineProperties(GlobeTranslucencyState.prototype, {  frontFaceAlphaByDistance: {    get: function () {      return this._frontFaceAlphaByDistance;    },  },  backFaceAlphaByDistance: {    get: function () {      return this._backFaceAlphaByDistance;    },  },  translucent: {    get: function () {      return this._frontFaceTranslucent;    },  },  sunVisibleThroughGlobe: {    get: function () {      return this._sunVisibleThroughGlobe;    },  },  environmentVisible: {    get: function () {      return this._environmentVisible;    },  },  useDepthPlane: {    get: function () {      return this._useDepthPlane;    },  },  numberOfTextureUniforms: {    get: function () {      return this._numberOfTextureUniforms;    },  },  rectangle: {    get: function () {      return this._rectangle;    },  },});GlobeTranslucencyState.prototype.update = function (scene) {  const globe = scene.globe;  if (!defined(globe) || !globe.show) {    this._frontFaceTranslucent = false;    this._backFaceTranslucent = false;    this._sunVisibleThroughGlobe = true;    this._environmentVisible = true;    this._useDepthPlane = false;    return;  }  this._frontFaceAlphaByDistance = updateAlphaByDistance(    globe.translucency.enabled,    globe.translucency.frontFaceAlpha,    globe.translucency.frontFaceAlphaByDistance,    this._frontFaceAlphaByDistance  );  this._backFaceAlphaByDistance = updateAlphaByDistance(    globe.translucency.enabled,    globe.translucency.backFaceAlpha,    globe.translucency.backFaceAlphaByDistance,    this._backFaceAlphaByDistance  );  this._frontFaceTranslucent = isFaceTranslucent(    globe.translucency.enabled,    this._frontFaceAlphaByDistance,    globe  );  this._backFaceTranslucent = isFaceTranslucent(    globe.translucency.enabled,    this._backFaceAlphaByDistance,    globe  );  this._requiresManualDepthTest = requiresManualDepthTest(this, scene, globe);  this._sunVisibleThroughGlobe = isSunVisibleThroughGlobe(this, scene);  this._environmentVisible = isEnvironmentVisible(this, scene);  this._useDepthPlane = useDepthPlane(this, scene);  this._numberOfTextureUniforms = getNumberOfTextureUniforms(this);  this._rectangle = Rectangle.clone(    globe.translucency.rectangle,    this._rectangle  );  gatherDerivedCommandRequirements(this, scene);};function updateAlphaByDistance(enabled, alpha, alphaByDistance, result) {  if (!enabled) {    result.nearValue = 1.0;    result.farValue = 1.0;    return result;  }  if (!defined(alphaByDistance)) {    result.nearValue = alpha;    result.farValue = alpha;    return result;  }  NearFarScalar.clone(alphaByDistance, result);  result.nearValue *= alpha;  result.farValue *= alpha;  return result;}function isFaceTranslucent(translucencyEnabled, alphaByDistance, globe) {  return (    translucencyEnabled &&    (globe.baseColor.alpha < 1.0 ||      alphaByDistance.nearValue < 1.0 ||      alphaByDistance.farValue < 1.0)  );}function isSunVisibleThroughGlobe(state, scene) {  // The sun is visible through the globe if the front and back faces are translucent when above ground  // or if front faces are translucent when below ground  const frontTranslucent = state._frontFaceTranslucent;  const backTranslucent = state._backFaceTranslucent;  return frontTranslucent && (scene.cameraUnderground || backTranslucent);}function isEnvironmentVisible(state, scene) {  // The environment is visible if the camera is above ground or underground with translucency  return !scene.cameraUnderground || state._frontFaceTranslucent;}function useDepthPlane(state, scene) {  // Use the depth plane when the camera is above ground and the globe is opaque  return !scene.cameraUnderground && !state._frontFaceTranslucent;}function requiresManualDepthTest(state, scene, globe) {  return (    state._frontFaceTranslucent &&    !state._backFaceTranslucent &&    !globe.depthTestAgainstTerrain &&    scene.mode !== SceneMode.SCENE2D &&    scene.context.depthTexture  );}function getNumberOfTextureUniforms(state) {  let numberOfTextureUniforms = 0;  if (state._frontFaceTranslucent) {    ++numberOfTextureUniforms; // classification texture  }  if (state._requiresManualDepthTest) {    ++numberOfTextureUniforms; // czm_globeDepthTexture for manual depth testing  }  return numberOfTextureUniforms;}function gatherDerivedCommandRequirements(state, scene) {  state._derivedCommandsLength = getDerivedCommandTypes(    state,    scene,    false,    false,    state._derivedCommandTypes  );  state._derivedBlendCommandsLength = getDerivedCommandTypes(    state,    scene,    true,    false,    state._derivedBlendCommandTypes  );  state._derivedPickCommandsLength = getDerivedCommandTypes(    state,    scene,    false,    true,    state._derivedPickCommandTypes  );  let i;  let derivedCommandKey = 0;  for (i = 0; i < state._derivedCommandsLength; ++i) {    derivedCommandKey |= 1 << state._derivedCommandTypes[i];  }  for (i = 0; i < state._derivedBlendCommandsLength; ++i) {    derivedCommandKey |= 1 << state._derivedBlendCommandTypes[i];  }  for (i = 0; i < state._derivedPickCommandsLength; ++i) {    derivedCommandKey |= 1 << state._derivedPickCommandTypes[i];  }  let derivedCommandsToUpdateLength = 0;  for (i = 0; i < derivedCommandsMaximumLength; ++i) {    if ((derivedCommandKey & (1 << i)) > 0) {      state._derivedCommandTypesToUpdate[derivedCommandsToUpdateLength++] = i;    }  }  state._derivedCommandsToUpdateLength = derivedCommandsToUpdateLength;  const derivedCommandsDirty = derivedCommandKey !== state._derivedCommandKey;  state._derivedCommandKey = derivedCommandKey;  state._derivedCommandsDirty = derivedCommandsDirty;  if (!defined(state._derivedCommandPacks) && state._frontFaceTranslucent) {    state._derivedCommandPacks = createDerivedCommandPacks();  }}function getDerivedCommandTypes(  state,  scene,  isBlendCommand,  isPickCommand,  types) {  let length = 0;  const frontTranslucent = state._frontFaceTranslucent;  const backTranslucent = state._backFaceTranslucent;  if (!frontTranslucent) {    // Don't use derived commands if the globe is opaque    return length;  }  const cameraUnderground = scene.cameraUnderground;  const requiresManualDepthTest = state._requiresManualDepthTest;  const translucentFrontFaceCommandType = isPickCommand    ? DerivedCommandType.PICK_FRONT_FACE    : requiresManualDepthTest    ? DerivedCommandType.TRANSLUCENT_FRONT_FACE_MANUAL_DEPTH_TEST    : DerivedCommandType.TRANSLUCENT_FRONT_FACE;  const translucentBackFaceCommandType = isPickCommand    ? DerivedCommandType.PICK_BACK_FACE    : requiresManualDepthTest    ? DerivedCommandType.TRANSLUCENT_BACK_FACE_MANUAL_DEPTH_TEST    : DerivedCommandType.TRANSLUCENT_BACK_FACE;  if (scene.mode === SceneMode.SCENE2D) {    types[length++] = DerivedCommandType.DEPTH_ONLY_FRONT_FACE;    types[length++] = translucentFrontFaceCommandType;    return length;  }  if (backTranslucent) {    // Push depth-only command for classification. Blend commands do not need to write depth.    // Push translucent commands for front and back faces.    if (!isBlendCommand) {      types[length++] = DerivedCommandType.DEPTH_ONLY_FRONT_AND_BACK_FACE;    }    if (cameraUnderground) {      types[length++] = translucentFrontFaceCommandType;      types[length++] = translucentBackFaceCommandType;    } else {      types[length++] = translucentBackFaceCommandType;      types[length++] = translucentFrontFaceCommandType;    }  } else {    // Push opaque command for the face that appears in back.    // Push depth-only command and translucent command for the face that appears in front.    // eslint-disable-next-line no-lonely-if    if (cameraUnderground) {      if (!isBlendCommand) {        types[length++] = DerivedCommandType.DEPTH_ONLY_BACK_FACE;      }      types[length++] = DerivedCommandType.OPAQUE_FRONT_FACE;      types[length++] = translucentBackFaceCommandType;    } else {      if (!isBlendCommand) {        types[length++] = DerivedCommandType.DEPTH_ONLY_FRONT_FACE;      }      types[length++] = DerivedCommandType.OPAQUE_BACK_FACE;      types[length++] = translucentFrontFaceCommandType;    }  }  return length;}function removeDefine(defines, defineToRemove) {  const index = defines.indexOf(defineToRemove);  if (index > -1) {    defines.splice(index, 1);  }}function hasDefine(defines, define) {  return defines.indexOf(define) > -1;}function getOpaqueFrontFaceShaderProgram(vs, fs) {  removeDefine(vs.defines, "TRANSLUCENT");  removeDefine(fs.defines, "TRANSLUCENT");}function getOpaqueBackFaceShaderProgram(vs, fs) {  removeDefine(vs.defines, "GROUND_ATMOSPHERE");  removeDefine(fs.defines, "GROUND_ATMOSPHERE");  removeDefine(vs.defines, "FOG");  removeDefine(fs.defines, "FOG");  removeDefine(vs.defines, "TRANSLUCENT");  removeDefine(fs.defines, "TRANSLUCENT");}function getDepthOnlyShaderProgram(vs, fs) {  if (    hasDefine(fs.defines, "TILE_LIMIT_RECTANGLE") ||    hasDefine(fs.defines, "ENABLE_CLIPPING_PLANES")  ) {    // Need to execute the full shader if discard is called    return;  }  const depthOnlyShader =    "void main() \n" + "{ \n" + "    gl_FragColor = vec4(1.0); \n" + "} \n";  fs.sources = [depthOnlyShader];}function getTranslucentShaderProgram(vs, fs) {  const sources = fs.sources;  const length = sources.length;  for (let i = 0; i < length; ++i) {    sources[i] = ShaderSource.replaceMain(      sources[i],      "czm_globe_translucency_main"    );  }  const globeTranslucencyMain =    "\n\n" +    "uniform sampler2D u_classificationTexture; \n" +    "void main() \n" +    "{ \n" +    "    vec2 st = gl_FragCoord.xy / czm_viewport.zw; \n" +    "#ifdef MANUAL_DEPTH_TEST \n" +    "    float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, st)); \n" +    "    if (logDepthOrDepth != 0.0) \n" +    "    { \n" +    "        vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, logDepthOrDepth); \n" +    "        float depthEC = eyeCoordinate.z / eyeCoordinate.w; \n" +    "        if (v_positionEC.z < depthEC) \n" +    "        { \n" +    "            discard; \n" +    "        } \n" +    "    } \n" +    "#endif \n" +    "    czm_globe_translucency_main(); \n" +    "    vec4 classificationColor = texture2D(u_classificationTexture, st); \n" +    "    if (classificationColor.a > 0.0) \n" +    "    { \n" +    "        // Reverse premultiplication process to get the correct composited result of the classification primitives \n" +    "        classificationColor.rgb /= classificationColor.a; \n" +    "    } \n" +    "    gl_FragColor = classificationColor * vec4(classificationColor.aaa, 1.0) + gl_FragColor * (1.0 - classificationColor.a); \n" +    "} \n";  sources.push(globeTranslucencyMain);}function getTranslucentBackFaceShaderProgram(vs, fs) {  getTranslucentShaderProgram(vs, fs);  removeDefine(vs.defines, "GROUND_ATMOSPHERE");  removeDefine(fs.defines, "GROUND_ATMOSPHERE");  removeDefine(vs.defines, "FOG");  removeDefine(fs.defines, "FOG");}function getTranslucentFrontFaceManualDepthTestShaderProgram(vs, fs) {  getTranslucentShaderProgram(vs, fs);  vs.defines.push("GENERATE_POSITION");  fs.defines.push("MANUAL_DEPTH_TEST");}function getTranslucentBackFaceManualDepthTestShaderProgram(vs, fs) {  getTranslucentBackFaceShaderProgram(vs, fs);  vs.defines.push("GENERATE_POSITION");  fs.defines.push("MANUAL_DEPTH_TEST");}function getPickShaderProgram(vs, fs) {  const pickShader =    "uniform sampler2D u_classificationTexture; \n" +    "void main() \n" +    "{ \n" +    "    vec2 st = gl_FragCoord.xy / czm_viewport.zw; \n" +    "    vec4 pickColor = texture2D(u_classificationTexture, st); \n" +    "    if (pickColor == vec4(0.0)) \n" +    "    { \n" +    "        discard; \n" +    "    } \n" +    "    gl_FragColor = pickColor; \n" +    "} \n";  fs.sources = [pickShader];}function getDerivedShaderProgram(  context,  shaderProgram,  derivedShaderProgram,  shaderProgramDirty,  getShaderProgramFunction,  cacheName) {  if (!defined(getShaderProgramFunction)) {    return shaderProgram;  }  if (!shaderProgramDirty && defined(derivedShaderProgram)) {    return derivedShaderProgram;  }  let shader = context.shaderCache.getDerivedShaderProgram(    shaderProgram,    cacheName  );  if (!defined(shader)) {    const attributeLocations = shaderProgram._attributeLocations;    const vs = shaderProgram.vertexShaderSource.clone();    const fs = shaderProgram.fragmentShaderSource.clone();    vs.defines = defined(vs.defines) ? vs.defines.slice(0) : [];    fs.defines = defined(fs.defines) ? fs.defines.slice(0) : [];    getShaderProgramFunction(vs, fs);    shader = context.shaderCache.createDerivedShaderProgram(      shaderProgram,      cacheName,      {        vertexShaderSource: vs,        fragmentShaderSource: fs,        attributeLocations: attributeLocations,      }    );  }  return shader;}function getOpaqueFrontFaceRenderState(renderState) {  renderState.cull.face = CullFace.BACK;  renderState.cull.enabled = true;}function getOpaqueBackFaceRenderState(renderState) {  renderState.cull.face = CullFace.FRONT;  renderState.cull.enabled = true;}function getDepthOnlyFrontFaceRenderState(renderState) {  renderState.cull.face = CullFace.BACK;  renderState.cull.enabled = true;  renderState.colorMask = {    red: false,    green: false,    blue: false,    alpha: false,  };}function getDepthOnlyBackFaceRenderState(renderState) {  renderState.cull.face = CullFace.FRONT;  renderState.cull.enabled = true;  renderState.colorMask = {    red: false,    green: false,    blue: false,    alpha: false,  };}function getDepthOnlyFrontAndBackFaceRenderState(renderState) {  renderState.cull.enabled = false;  renderState.colorMask = {    red: false,    green: false,    blue: false,    alpha: false,  };}function getTranslucentFrontFaceRenderState(renderState) {  renderState.cull.face = CullFace.BACK;  renderState.cull.enabled = true;  renderState.depthMask = false;  renderState.blending = BlendingState.ALPHA_BLEND;}function getTranslucentBackFaceRenderState(renderState) {  renderState.cull.face = CullFace.FRONT;  renderState.cull.enabled = true;  renderState.depthMask = false;  renderState.blending = BlendingState.ALPHA_BLEND;}function getPickFrontFaceRenderState(renderState) {  renderState.cull.face = CullFace.BACK;  renderState.cull.enabled = true;  renderState.blending.enabled = false;}function getPickBackFaceRenderState(renderState) {  renderState.cull.face = CullFace.FRONT;  renderState.cull.enabled = true;  renderState.blending.enabled = false;}function getDerivedRenderState(  renderState,  derivedRenderState,  renderStateDirty,  getRenderStateFunction,  cache) {  if (!defined(getRenderStateFunction)) {    return renderState;  }  if (!renderStateDirty && defined(derivedRenderState)) {    return derivedRenderState;  }  let cachedRenderState = cache[renderState.id];  if (!defined(cachedRenderState)) {    const rs = RenderState.getState(renderState);    getRenderStateFunction(rs);    cachedRenderState = RenderState.fromCache(rs);    cache[renderState.id] = cachedRenderState;  }  return cachedRenderState;}function getTranslucencyUniformMap(state) {  return {    u_classificationTexture: function () {      return state._globeTranslucencyFramebuffer.classificationTexture;    },  };}function getDerivedUniformMap(  state,  uniformMap,  derivedUniformMap,  uniformMapDirty,  getDerivedUniformMapFunction) {  if (!defined(getDerivedUniformMapFunction)) {    return uniformMap;  }  if (!uniformMapDirty && defined(derivedUniformMap)) {    return derivedUniformMap;  }  return combine(uniformMap, getDerivedUniformMapFunction(state), false);}function DerivedCommandPack(options) {  this.pass = options.pass;  this.pickOnly = options.pickOnly;  this.getShaderProgramFunction = options.getShaderProgramFunction;  this.getRenderStateFunction = options.getRenderStateFunction;  this.getUniformMapFunction = options.getUniformMapFunction;  this.renderStateCache = {};}function createDerivedCommandPacks() {  return [    // opaqueFrontFaceCommand    new DerivedCommandPack({      pass: Pass.GLOBE,      pickOnly: false,      getShaderProgramFunction: getOpaqueFrontFaceShaderProgram,      getRenderStateFunction: getOpaqueFrontFaceRenderState,      getUniformMapFunction: undefined,    }),    // opaqueBackFaceCommand    new DerivedCommandPack({      pass: Pass.GLOBE,      pickOnly: false,      getShaderProgramFunction: getOpaqueBackFaceShaderProgram,      getRenderStateFunction: getOpaqueBackFaceRenderState,      getUniformMapFunction: undefined,    }),    // depthOnlyFrontFaceCommand    new DerivedCommandPack({      pass: Pass.GLOBE,      pickOnly: false,      getShaderProgramFunction: getDepthOnlyShaderProgram,      getRenderStateFunction: getDepthOnlyFrontFaceRenderState,      getUniformMapFunction: undefined,    }),    // depthOnlyBackFaceCommand    new DerivedCommandPack({      pass: Pass.GLOBE,      pickOnly: false,      getShaderProgramFunction: getDepthOnlyShaderProgram,      getRenderStateFunction: getDepthOnlyBackFaceRenderState,      getUniformMapFunction: undefined,    }),    // depthOnlyFrontAndBackFaceCommand    new DerivedCommandPack({      pass: Pass.GLOBE,      pickOnly: false,      getShaderProgramFunction: getDepthOnlyShaderProgram,      getRenderStateFunction: getDepthOnlyFrontAndBackFaceRenderState,      getUniformMapFunction: undefined,    }),    // translucentFrontFaceCommand    new DerivedCommandPack({      pass: Pass.TRANSLUCENT,      pickOnly: false,      getShaderProgramFunction: getTranslucentShaderProgram,      getRenderStateFunction: getTranslucentFrontFaceRenderState,      getUniformMapFunction: getTranslucencyUniformMap,    }),    // translucentBackFaceCommand    new DerivedCommandPack({      pass: Pass.TRANSLUCENT,      pickOnly: false,      getShaderProgramFunction: getTranslucentBackFaceShaderProgram,      getRenderStateFunction: getTranslucentBackFaceRenderState,      getUniformMapFunction: getTranslucencyUniformMap,    }),    // translucentFrontFaceManualDepthTestCommand    new DerivedCommandPack({      pass: Pass.TRANSLUCENT,      pickOnly: false,      getShaderProgramFunction: getTranslucentFrontFaceManualDepthTestShaderProgram,      getRenderStateFunction: getTranslucentFrontFaceRenderState,      getUniformMapFunction: getTranslucencyUniformMap,    }),    // translucentBackFaceManualDepthTestCommand    new DerivedCommandPack({      pass: Pass.TRANSLUCENT,      pickOnly: false,      getShaderProgramFunction: getTranslucentBackFaceManualDepthTestShaderProgram,      getRenderStateFunction: getTranslucentBackFaceRenderState,      getUniformMapFunction: getTranslucencyUniformMap,    }),    // pickFrontFaceCommand    new DerivedCommandPack({      pass: Pass.TRANSLUCENT,      pickOnly: true,      getShaderProgramFunction: getPickShaderProgram,      getRenderStateFunction: getPickFrontFaceRenderState,      getUniformMapFunction: getTranslucencyUniformMap,    }),    // pickBackFaceCommand    new DerivedCommandPack({      pass: Pass.TRANSLUCENT,      pickOnly: true,      getShaderProgramFunction: getPickShaderProgram,      getRenderStateFunction: getPickBackFaceRenderState,      getUniformMapFunction: getTranslucencyUniformMap,    }),  ];}const derivedCommandNames = new Array(derivedCommandsMaximumLength);const derivedCommandPacks = new Array(derivedCommandsMaximumLength);GlobeTranslucencyState.prototype.updateDerivedCommands = function (  command,  frameState) {  const derivedCommandTypes = this._derivedCommandTypesToUpdate;  const derivedCommandsLength = this._derivedCommandsToUpdateLength;  if (derivedCommandsLength === 0) {    return;  }  for (let i = 0; i < derivedCommandsLength; ++i) {    derivedCommandPacks[i] = this._derivedCommandPacks[derivedCommandTypes[i]];    derivedCommandNames[i] = DerivedCommandNames[derivedCommandTypes[i]];  }  updateDerivedCommands(    this,    command,    derivedCommandsLength,    derivedCommandTypes,    derivedCommandNames,    derivedCommandPacks,    frameState  );};function updateDerivedCommands(  state,  command,  derivedCommandsLength,  derivedCommandTypes,  derivedCommandNames,  derivedCommandPacks,  frameState) {  let derivedCommandsObject = command.derivedCommands.globeTranslucency;  const derivedCommandsDirty = state._derivedCommandsDirty;  if (    command.dirty ||    !defined(derivedCommandsObject) ||    derivedCommandsDirty  ) {    command.dirty = false;    if (!defined(derivedCommandsObject)) {      derivedCommandsObject = {};      command.derivedCommands.globeTranslucency = derivedCommandsObject;    }    const frameNumber = frameState.frameNumber;    const uniformMapDirtyFrame = defaultValue(      derivedCommandsObject.uniformMapDirtyFrame,      0    );    const shaderProgramDirtyFrame = defaultValue(      derivedCommandsObject.shaderProgramDirtyFrame,      0    );    const renderStateDirtyFrame = defaultValue(      derivedCommandsObject.renderStateDirtyFrame,      0    );    const uniformMapDirty =      derivedCommandsObject.uniformMap !== command.uniformMap;    const shaderProgramDirty =      derivedCommandsObject.shaderProgramId !== command.shaderProgram.id;    const renderStateDirty =      derivedCommandsObject.renderStateId !== command.renderState.id;    if (uniformMapDirty) {      derivedCommandsObject.uniformMapDirtyFrame = frameNumber;    }    if (shaderProgramDirty) {      derivedCommandsObject.shaderProgramDirtyFrame = frameNumber;    }    if (renderStateDirty) {      derivedCommandsObject.renderStateDirtyFrame = frameNumber;    }    derivedCommandsObject.uniformMap = command.uniformMap;    derivedCommandsObject.shaderProgramId = command.shaderProgram.id;    derivedCommandsObject.renderStateId = command.renderState.id;    for (let i = 0; i < derivedCommandsLength; ++i) {      const derivedCommandPack = derivedCommandPacks[i];      const derivedCommandType = derivedCommandTypes[i];      const derivedCommandName = derivedCommandNames[i];      let derivedCommand = derivedCommandsObject[derivedCommandName];      let derivedUniformMap;      let derivedShaderProgram;      let derivedRenderState;      if (defined(derivedCommand)) {        derivedUniformMap = derivedCommand.uniformMap;        derivedShaderProgram = derivedCommand.shaderProgram;        derivedRenderState = derivedCommand.renderState;      } else {        derivedUniformMap = undefined;        derivedShaderProgram = undefined;        derivedRenderState = undefined;      }      derivedCommand = DrawCommand.shallowClone(command, derivedCommand);      derivedCommandsObject[derivedCommandName] = derivedCommand;      const derivedUniformMapDirtyFrame = defaultValue(        derivedCommand.derivedCommands.uniformMapDirtyFrame,        0      );      const derivedShaderProgramDirtyFrame = defaultValue(        derivedCommand.derivedCommands.shaderProgramDirtyFrame,        0      );      const derivedRenderStateDirtyFrame = defaultValue(        derivedCommand.derivedCommands.renderStateDirtyFrame,        0      );      const derivedUniformMapDirty =        uniformMapDirty || derivedUniformMapDirtyFrame < uniformMapDirtyFrame;      const derivedShaderProgramDirty =        shaderProgramDirty ||        derivedShaderProgramDirtyFrame < shaderProgramDirtyFrame;      const derivedRenderStateDirty =        renderStateDirty ||        derivedRenderStateDirtyFrame < renderStateDirtyFrame;      if (derivedUniformMapDirty) {        derivedCommand.derivedCommands.uniformMapDirtyFrame = frameNumber;      }      if (derivedShaderProgramDirty) {        derivedCommand.derivedCommands.shaderProgramDirtyFrame = frameNumber;      }      if (derivedRenderStateDirty) {        derivedCommand.derivedCommands.renderStateDirtyFrame = frameNumber;      }      derivedCommand.derivedCommands.type = derivedCommandType;      derivedCommand.pass = derivedCommandPack.pass;      derivedCommand.pickOnly = derivedCommandPack.pickOnly;      derivedCommand.uniformMap = getDerivedUniformMap(        state,        command.uniformMap,        derivedUniformMap,        derivedUniformMapDirty,        derivedCommandPack.getUniformMapFunction      );      derivedCommand.shaderProgram = getDerivedShaderProgram(        frameState.context,        command.shaderProgram,        derivedShaderProgram,        derivedShaderProgramDirty,        derivedCommandPack.getShaderProgramFunction,        derivedCommandName      );      derivedCommand.renderState = getDerivedRenderState(        command.renderState,        derivedRenderState,        derivedRenderStateDirty,        derivedCommandPack.getRenderStateFunction,        derivedCommandPack.renderStateCache      );    }  }}GlobeTranslucencyState.prototype.pushDerivedCommands = function (  command,  isBlendCommand,  frameState) {  const picking = frameState.passes.pick;  if (picking && isBlendCommand) {    // No need to push blend commands in the pick pass    return;  }  let derivedCommandTypes = this._derivedCommandTypes;  let derivedCommandsLength = this._derivedCommandsLength;  if (picking) {    derivedCommandTypes = this._derivedPickCommandTypes;    derivedCommandsLength = this._derivedPickCommandsLength;  } else if (isBlendCommand) {    derivedCommandTypes = this._derivedBlendCommandTypes;    derivedCommandsLength = this._derivedBlendCommandsLength;  }  if (derivedCommandsLength === 0) {    // No derived commands to push so just push the globe command    frameState.commandList.push(command);    return;  }  // Push derived commands  const derivedCommands = command.derivedCommands.globeTranslucency;  for (let i = 0; i < derivedCommandsLength; ++i) {    const derivedCommandName = DerivedCommandNames[derivedCommandTypes[i]];    frameState.commandList.push(derivedCommands[derivedCommandName]);  }};function executeCommandsMatchingType(  commands,  commandsLength,  executeCommandFunction,  scene,  context,  passState,  types) {  for (let i = 0; i < commandsLength; ++i) {    const command = commands[i];    const type = command.derivedCommands.type;    if (!defined(types) || types.indexOf(type) > -1) {      executeCommandFunction(command, scene, context, passState);    }  }}function executeCommands(  commands,  commandsLength,  executeCommandFunction,  scene,  context,  passState) {  for (let i = 0; i < commandsLength; ++i) {    executeCommandFunction(commands[i], scene, context, passState);  }}const opaqueTypes = [  DerivedCommandType.OPAQUE_FRONT_FACE,  DerivedCommandType.OPAQUE_BACK_FACE,];const depthOnlyTypes = [  DerivedCommandType.DEPTH_ONLY_FRONT_FACE,  DerivedCommandType.DEPTH_ONLY_BACK_FACE,  DerivedCommandType.DEPTH_ONLY_FRONT_AND_BACK_FACE,];GlobeTranslucencyState.prototype.executeGlobeCommands = function (  frustumCommands,  executeCommandFunction,  globeTranslucencyFramebuffer,  scene,  passState) {  const context = scene.context;  const globeCommands = frustumCommands.commands[Pass.GLOBE];  const globeCommandsLength = frustumCommands.indices[Pass.GLOBE];  if (globeCommandsLength === 0) {    return;  }  this._globeTranslucencyFramebuffer = globeTranslucencyFramebuffer;  globeTranslucencyFramebuffer.clearClassification(context, passState);  // Render opaque commands like normal  executeCommandsMatchingType(    globeCommands,    globeCommandsLength,    executeCommandFunction,    scene,    context,    passState,    opaqueTypes  );};GlobeTranslucencyState.prototype.executeGlobeClassificationCommands = function (  frustumCommands,  executeCommandFunction,  globeTranslucencyFramebuffer,  scene,  passState) {  const context = scene.context;  const globeCommands = frustumCommands.commands[Pass.GLOBE];  const globeCommandsLength = frustumCommands.indices[Pass.GLOBE];  const classificationCommands =    frustumCommands.commands[Pass.TERRAIN_CLASSIFICATION];  const classificationCommandsLength =    frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION];  if (globeCommandsLength === 0 || classificationCommandsLength === 0) {    return;  }  const frontTranslucent = this._frontFaceTranslucent;  const backTranslucent = this._backFaceTranslucent;  if (!frontTranslucent || !backTranslucent) {    // Render classification on opaque faces like normal    executeCommands(      classificationCommands,      classificationCommandsLength,      executeCommandFunction,      scene,      context,      passState    );  }  if (!frontTranslucent && !backTranslucent) {    // No translucent commands to render. Skip translucent classification.    return;  }  this._globeTranslucencyFramebuffer = globeTranslucencyFramebuffer;  const originalGlobeDepthTexture = context.uniformState.globeDepthTexture;  const originalFramebuffer = passState.framebuffer;  // Render to internal framebuffer and get the first depth peel  passState.framebuffer =    globeTranslucencyFramebuffer.classificationFramebuffer;  executeCommandsMatchingType(    globeCommands,    globeCommandsLength,    executeCommandFunction,    scene,    context,    passState,    depthOnlyTypes  );  if (context.depthTexture) {    // Pack depth into separate texture for ground polylines and textured ground primitives    const packedDepthTexture = globeTranslucencyFramebuffer.packDepth(      context,      passState    );    context.uniformState.globeDepthTexture = packedDepthTexture;  }  // Render classification on translucent faces  executeCommands(    classificationCommands,    classificationCommandsLength,    executeCommandFunction,    scene,    context,    passState  );  // Unset temporary state  context.uniformState.globeDepthTexture = originalGlobeDepthTexture;  passState.framebuffer = originalFramebuffer;};export default GlobeTranslucencyState;
 |