function PostProcessStage(options) {
  options = options ?? Frozen.EMPTY_OBJECT;
  const {
    name = createGuid(),
    fragmentShader,
    uniforms,
    textureScale = 1.0,
    forcePowerOfTwo = false,
    sampleMode = PostProcessStageSampleMode.NEAREST,
    pixelFormat = PixelFormat.RGBA,
    pixelDatatype = PixelDatatype.UNSIGNED_BYTE,
    clearColor = Color.BLACK,
    scissorRectangle,
  } = options;

  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.string("options.fragmentShader", fragmentShader);
  Check.typeOf.number.greaterThan("options.textureScale", textureScale, 0.0);
  Check.typeOf.number.lessThanOrEquals(
    "options.textureScale",
    textureScale,
    1.0,
  );
  if (!PixelFormat.isColorFormat(pixelFormat)) {
    throw new DeveloperError("options.pixelFormat must be a color format.");
  }
  //>>includeEnd('debug');

  this._fragmentShader = fragmentShader;
  this._uniforms = uniforms;
  this._textureScale = textureScale;
  this._forcePowerOfTwo = forcePowerOfTwo;
  this._sampleMode = sampleMode;
  this._pixelFormat = pixelFormat;
  this._pixelDatatype = pixelDatatype;
  this._clearColor = clearColor;

  this._uniformMap = undefined;
  this._command = undefined;

  this._colorTexture = undefined;
  this._depthTexture = undefined;
  this._idTexture = undefined;

  this._actualUniforms = {};
  this._dirtyUniforms = [];
  this._texturesToRelease = [];
  this._texturesToCreate = [];
  this._texturePromise = undefined;

  const passState = new PassState();
  passState.scissorTest = {
    enabled: true,
    rectangle: defined(scissorRectangle)
      ? BoundingRectangle.clone(scissorRectangle)
      : new BoundingRectangle(),
  };
  this._passState = passState;

  this._ready = false;

  this._name = name;

  this._logDepthChanged = undefined;
  this._useLogDepth = undefined;

  this._selectedIdTexture = undefined;
  this._selected = undefined;
  this._selectedShadow = undefined;
  this._parentSelected = undefined;
  this._parentSelectedShadow = undefined;
  this._combinedSelected = undefined;
  this._combinedSelectedShadow = undefined;
  this._selectedLength = 0;
  this._parentSelectedLength = 0;
  this._selectedDirty = true;

  // set by PostProcessStageCollection
  this._textureCache = undefined;
  this._index = undefined;

  /**
   * Whether or not to execute this post-process stage when ready.
   *
   * @type {boolean}
   */
  this.enabled = true;
  this._enabled = true;
}
Runs a post-process stage on either the texture rendered by the scene or the output of a previous post-process stage.

@alias PostProcessStage
@constructor

@param {object} options An object with the following properties:
@param {string} options.fragmentShader The fragment shader to use. The default <code>sampler2D</code> uniforms are <code>colorTexture</code> and <code>depthTexture</code>. The color texture is the output of rendering the scene or the previous stage. The depth texture is the output from rendering the scene. The shader should contain one or both uniforms. There is also a <code>vec2</code> varying named <code>v_textureCoordinates</code> that can be used to sample the textures.
@param {object} [options.uniforms] An object whose properties will be used to set the shaders uniforms. The properties can be constant values or a function. A constant value can also be a URI, data URI, or HTML element to use as a texture.
@param {number} [options.textureScale=1.0] A number in the range (0.0, 1.0] used to scale the texture dimensions. A scale of 1.0 will render this post-process stage  to a texture the size of the viewport.
@param {boolean} [options.forcePowerOfTwo=false] Whether or not to force the texture dimensions to be both equal powers of two. The power of two will be the next power of two of the minimum of the dimensions.
@param {PostProcessStageSampleMode} [options.sampleMode=PostProcessStageSampleMode.NEAREST] How to sample the input color texture.
@param {PixelFormat} [options.pixelFormat=PixelFormat.RGBA] The color pixel format of the output texture.
@param {PixelDatatype} [options.pixelDatatype=PixelDatatype.UNSIGNED_BYTE] The pixel data type of the output texture.
@param {Color} [options.clearColor=Color.BLACK] The color to clear the output texture to.
@param {BoundingRectangle} [options.scissorRectangle] The rectangle to use for the scissor test.
@param {string} [options.name=createGuid()] The unique name of this post-process stage for reference by other stages in a composite. If a name is not supplied, a GUID will be generated.

@exception {DeveloperError} options.textureScale must be greater than 0.0 and less than or equal to 1.0.
@exception {DeveloperError} options.pixelFormat must be a color format.
@exception {DeveloperError} When options.pixelDatatype is FLOAT, this WebGL implementation must support floating point textures. Check context.floatingPointTexture.

@see PostProcessStageComposite

@example
// Simple stage to change the color
const fs =`
    uniform sampler2D colorTexture;
    in vec2 v_textureCoordinates;
    uniform float scale;
    uniform vec3 offset;
    void main() {
        vec4 color = texture(colorTexture, v_textureCoordinates);
        out_FragColor = vec4(color.rgb * scale + offset, 1.0);
    }`;
scene.postProcessStages.add(new Cesium.PostProcessStage({
    fragmentShader : fs,
    uniforms : {
        scale : 1.1,
        offset : function() {
            return new Cesium.Cartesian3(0.1, 0.2, 0.3);
        }
    }
}));

@example
// Simple stage to change the color of what is selected.
// If czm_selected returns true, the current fragment belongs to geometry in the selected array.
const fs =`
    uniform sampler2D colorTexture;
    in vec2 v_textureCoordinates;
    uniform vec4 highlight;
    void main() {
        vec4 color = texture(colorTexture, v_textureCoordinates);
        if (czm_selected()) {
            vec3 highlighted = highlight.a * highlight.rgb + (1.0 - highlight.a) * color.rgb;
            out_FragColor = vec4(highlighted, 1.0);
        } else {
            out_FragColor = color;
        }
    }`;
const stage = scene.postProcessStages.add(new Cesium.PostProcessStage({
    fragmentShader : fs,
    uniforms : {
        highlight : function() {
            return new Cesium.Color(1.0, 0.0, 0.0, 0.5);
        }
    }
}));
stage.selected = [cesium3DTileFeature];