static _buildSampleAndBlendFunction(shaderBuilder, imageryFlags) {
    const functionId = "sampleAndBlend";
    const signature =
      ImageryPipelineStage._createSampleAndBlendFunctionSignature(imageryFlags);
    shaderBuilder.addFunction(
      functionId,
      signature,
      ShaderDestination.FRAGMENT,
    );

    shaderBuilder.addFunctionLines(functionId, [`float effectiveAlpha = 1.0;`]);
    if (imageryFlags.alpha) {
      shaderBuilder.addFunctionLines(functionId, [
        `effectiveAlpha = textureAlpha;`,
      ]);
    }
    shaderBuilder.addFunctionLines(functionId, [
      // This is the part that is documented as "This crazy step stuff"
      // in GlobeFS.glsl. Using the if-approach here...
      `if (textureCoordinates.x < textureCoordinateRectangle.x) effectiveAlpha = 0.0;`,
      `if (textureCoordinates.x > textureCoordinateRectangle.z) effectiveAlpha = 0.0;`,
      `if (textureCoordinates.y < textureCoordinateRectangle.y) effectiveAlpha = 0.0;`,
      `if (textureCoordinates.y > textureCoordinateRectangle.w) effectiveAlpha = 0.0;`,

      `vec2 translation = textureCoordinateTranslationAndScale.xy;`,
      `vec2 scale = textureCoordinateTranslationAndScale.zw;`,
      `vec2 effectiveTextureCoordinates = textureCoordinates * scale + translation;`,
      `vec4 value = texture(textureToSample, effectiveTextureCoordinates);`,
      `value = czm_srgbToLinear(value);`,

      `vec3 color = value.rgb;`,
      `float alpha = value.a;`,
    ]);

    if (imageryFlags.colorToAlpha) {
      shaderBuilder.addFunctionLines(functionId, [
        `vec3 colorDiff = abs(color.rgb - colorToAlpha.rgb);`,
        `colorDiff.r = czm_maximumComponent(colorDiff);`,
        `alpha = czm_branchFreeTernary(colorDiff.r < colorToAlpha.a, 0.0, alpha);`,
      ]);
    }

    if (imageryFlags.gamma) {
      shaderBuilder.addFunctionLines(functionId, [
        `color = pow(color, vec3(textureOneOverGamma));`,
      ]);
    } else {
      shaderBuilder.addFunctionLines(functionId, [
        `vec4 tempColor = czm_gammaCorrect(vec4(color, alpha));`,
        `color = tempColor.rgb;`,
        `alpha = tempColor.a;`,
      ]);
    }

    if (imageryFlags.brightness) {
      shaderBuilder.addFunctionLines(functionId, [
        `color = mix(vec3(0.0), color, textureBrightness);`,
      ]);
    }

    if (imageryFlags.contrast) {
      shaderBuilder.addFunctionLines(functionId, [
        `color = mix(vec3(0.5), color, textureContrast);`,
      ]);
    }
    if (imageryFlags.hue) {
      shaderBuilder.addFunctionLines(functionId, [
        `color = czm_hue(color, textureHue);`,
      ]);
    }

    if (imageryFlags.saturation) {
      shaderBuilder.addFunctionLines(functionId, [
        `color = czm_saturation(color, textureSaturation);`,
      ]);
    }

    shaderBuilder.addFunctionLines(functionId, [
      `float sourceAlpha = alpha * effectiveAlpha;`,
      `float outAlpha = mix(previousColor.a, 1.0, sourceAlpha);`,
      `outAlpha += sign(outAlpha) - 1.0;`,
      `vec3 outColor = mix(previousColor.rgb * previousColor.a, color, sourceAlpha) / outAlpha;`,
      // See comments in https://github.com/CesiumGS/cesium/blob/6cc004aaff586bb59f07f199216ae511014cf5a9/packages/engine/Source/Shaders/GlobeFS.glsl#L166
      `vec4 result = vec4(outColor, max(outAlpha, 0.0));`,
    ]);

    // Debug mode: Draw boundaries of imagery in red
    if (debugDrawImageryBoundaries) {
      shaderBuilder.addFunctionLines(functionId, [
        `if (abs(textureCoordinates.x - textureCoordinateRectangle.x) < (1.0/256.0) || `,
        `    abs(textureCoordinates.x - textureCoordinateRectangle.z) < (1.0/256.0) || `,
        `    abs(textureCoordinates.y - textureCoordinateRectangle.y) < (1.0/256.0) || `,
        `    abs(textureCoordinates.y - textureCoordinateRectangle.w) < (1.0/256.0))`,
        `{`,
        `    result = vec4(1.0, 0.0, 0.0, effectiveAlpha);`,
        `}`,
      ]);
    }

    shaderBuilder.addFunctionLines(functionId, [`return result;`]);
  }
Build the `sampleAndBlend` function that will be called for each imagery,
to combine the previous pixel color with the respective imagery input.

The function that is built here resembles the function that was originally defined at
https://github.com/CesiumGS/cesium/blob/6cc004aaff586bb59f07f199216ae511014cf5a9/packages/engine/Source/Shaders/GlobeFS.glsl#L166

However, for the function that is built here, the signature will
reflect the actual features that are required for the imagery:
For example, the `float textureAlpha` parameter will only be
present when `imageryFlags.alpha` is `true`.

@param {ShaderBuilder} shaderBuilder The shader builder
@param {ImageryFlags} imageryFlags The imagery flags