showGradientColorMap(id, duration, toColorWhite, toColorBlack, toColorMid) {
    if (duration == null) { duration = 0.0; }

    // stop current top of stack
    if (this._gradientMapStack.length > 0) {
      const currentGradientMapData = this._gradientMapStack[this._gradientMapStack.length - 1];
      if (currentGradientMapData.action != null && !currentGradientMapData.action.isDone()) {
        this.getScene().stopAction(currentGradientMapData.action);
      }
    }

    // auto detect mid point if none is provided
    if (!toColorMid && toColorWhite && toColorBlack) {
      toColorMid = cc.color(
        cc.lerp(toColorWhite.r, toColorBlack.r, 0.5),
        cc.lerp(toColorWhite.g, toColorBlack.g, 0.5),
        cc.lerp(toColorWhite.b, toColorBlack.b, 0.5),
        cc.lerp(toColorWhite.a, toColorBlack.a, 0.5),
      );
    }

    // get from colors
    const fromColorWhite = this.getPhaseGradientColorMapWhiteColor();
    const fromColorMid = this.getPhaseGradientColorMapMidColor();
    const fromColorBlack = this.getPhaseGradientColorMapBlackColor();

    // find gradient map data
    let gradientMapData;
    let gradientMapDataIndex = -1;
    for (let i = 0, il = this._gradientMapStack.length; i < il; i++) {
      if (this._gradientMapStack[i].id === id) {
        gradientMapDataIndex = i;
        break;
      }
    }
    if (gradientMapDataIndex != -1) {
      if (gradientMapDataIndex === this._gradientMapStack.length - 1) {
        // get data and leave it on top
        gradientMapData = this._gradientMapStack[gradientMapDataIndex];
      } else {
        // extract data from wherever it is in stack and push to top
        gradientMapData = this._gradientMapStack.splice(gradientMapDataIndex, 1)[0];
        this._gradientMapStack.push(gradientMapData);
      }

      // check if the colors have changed
      if (toColorWhite != null && !cc.colorEqual(gradientMapData.toColorWhite, toColorWhite)) {
        gradientMapData.toColorWhite = toColorWhite;
      }
      if (toColorMid != null && !cc.colorEqual(gradientMapData.toColorMid, toColorMid)) {
        gradientMapData.toColorMid = toColorMid;
      }
      if (toColorBlack != null && !cc.colorEqual(gradientMapData.toColorBlack, toColorBlack)) {
        gradientMapData.toColorBlack = toColorBlack;
      }
    } else {
      // create gradient map data
      gradientMapData = {
        id,
        toColorWhite: toColorWhite || cc.color(0.0, 0.0, 0.0, 0.0),
        toColorMid: toColorMid || cc.color(0.0, 0.0, 0.0, 0.0),
        toColorBlack: toColorBlack || cc.color(0.0, 0.0, 0.0, 0.0),
        action: null,
      };

      // push gradient map to top of stack
      this._gradientMapStack.push(gradientMapData);
    }

    // run gradient map action
    gradientMapData.action = GradientColorMap.create(duration, fromColorWhite, fromColorMid, fromColorBlack, gradientMapData.toColorWhite, gradientMapData.toColorMid, gradientMapData.toColorBlack);
    this.getScene().runAction(gradientMapData.action);
  }
Sets the current Gradient Color Map to a target.
@param {Number} id
@param {Number} [duration=0.0]
@param {cc.Color} [toColorWhite=0] target white point
@param {cc.Color} [toColorBlack=0] target black point
@param {cc.Color} [toColorMid=0] target mid point )optional