# Built-in pipeline

In addition to the built-in nodes, the mini game framework also provides built-in pipelines to meet different needs. There are two pipelines by default.

# Forward rendering pipeline

The forward rendering pipeline ForwardBaseRG is a standard pipeline built into the small game framework, which integrates Forward Base and Forward Add, and at the same time incorporates UI, Gizmo, and Skybox.

As a built-in pipeline, in order to integrate with other parts, it is constructed based on the camera Camera, and each active camera in the scene has its own sub-rendered image. So the basic process of this built-in pipeline is:

onCamerasChange -> Traverse cameras -> Generate subgraphs for each camera -> Connect these subgraphs end to end

The graph itself is cached for the subgraphs to avoid reconstructing the entire graph every time it is modified. In addition to building the graph, another important part is the creation and update of the global uniform, which directly affects the update of each rendering node. In addition, generally speaking, the registration of the default downgrade effect is also carried out here.

Since all aspects are involved, the code of the entire built-in pipeline will be directly commented out below:

export default class ForwardBaseRG extends RenderGraph {
  // Has the degraded shadow Effect been registered?
  protected _shadowFallbackRegistered: boolean = false;
  // Global Uniform
  protected _globalUniforms!: {
    // Global Uniform in the ForwardBase stage
    fbUniforms: engine.UniformBlock;
    // Global Uniform in the ForwardAdd phase
    faUniforms: engine.UniformBlock;
    // Global Uniform in the UI stage
    uiUniforms?: engine.UniformBlock;
    // Global Uniform in the shadow phase
    scUniforms?: engine.UniformBlock;
    // #if defined(EDITOR)
    rcUniforms?: engine.UniformBlock;
    // #endif
  };
  protected _subGraphs: {[nodeId: number]: BaseCamera} = {};

  // View used to clear the screen by default
  protected _defaultClearView?: engine.View;

  public onActive(context: RenderSystem) {
    this._globalUniforms = {
      fbUniforms: new engine.UniformBlock(forwardBaseUD),
      faUniforms: new engine.UniformBlock(forwardAddUD),
      uiUniforms: new engine.UniformBlock(forwardBaseUD),
      scUniforms: new engine.UniformBlock(shadowCaterUD),
      // #if defined(EDITOR)
      rcUniforms: new engine.UniformBlock(forwardBaseUD)
      // #endif
    }

    this._defaultClearView = new engine.View({
      passAction: {
        clearColor: [0, 0, 0, 1],
        colorAction: engine.ELoadAction.CLEAR
      },
      viewport: {x: 0, y: 0, w: 1, h: 1},
      scissor: {x: 0, y: 0, w: 1, h: 1}
    });

    this._rebuildRG(context.cameras, context.changedCameras);
  }

  public onCamerasChange(cameras: BaseCamera[], changeCameras: BaseCamera[]) {
    this._rebuildRG(cameras, changeCameras);
  }

  // Create the whole picture by `cameras`, the camera list has been sorted
  protected _rebuildRG(cameras: BaseCamera[], changeCameras: BaseCamera[]) {
    // First clear the entire picture, but keep the sub-pictures that Camera has not changed
    const cachedCameras: {[cameraId: number]: TRGNodeAny} = {};
    this._clear((node: TRGNodeAny) => {
      const camera = this._subGraphs[node.id];
      if (camera && changeCameras.indexOf(camera) <0) {
        cachedCameras[camera.id] = node;
        return true;
      }

      delete this._subGraphs[node.id];
      return false;
    });
    let lastNode: TRGNodeAny;

    // If there is only one camera and it is a UI camera, the screen is forced to clear once, because the main UI camera is not clear by default
    if (cameras[0] instanceof UICamera && (!cameras[0].renderTarget || cameras[0].renderTarget instanceof Screen)) {
      const defaultCameraNode = this.createNode<RGGenViewNode>(`default-view-gen`, RGGenViewNode, {viewObject: {view: this._defaultClearView!}});
      const defaultRtNode = this.createNode<RGGenRenderTargetNode>('rt-screen', RGGenRenderTargetNode, {createRenderTarget: () => this.context.screen});
      const defaultClearNode = this.createNode<RGClearNode>('default-view-clear', RGClearNode, {});
      this.connect(defaultCameraNode, defaultClearNode,'camera');
      this.connect(defaultRtNode, defaultClearNode,'renderTarget');
      lastNode = defaultClearNode;
    }

    // Use the cache to create all subgraph nodes
    cameras.forEach(camera => {
      let subGraph = cachedCameras[camera.id] as TForwardBaseSubGraphNode;

      if (!subGraph) {
        subGraph = this.createNode<TForwardBaseSubGraphNode>(`subGraph-${camera.entity.name}`, RGSubGraphNode, {
          // class of subgraph
          RGClass: ForwardBaseSubGraph,
          options: {
            ...this._globalUniforms,
            camera
          }
        });
        this._subGraphs[subGraph.id] = camera;
      }

      lastNode && this.connect(lastNode, subGraph);
      lastNode = subGraph;
    });
  }

  // Before the start of each frame rendering, set the global Uniform
  public onExecuteBegin(context: RenderSystem) {
    const dirL = context.lights.mainDirectionalLight;

    const uniforms = this._globalUniforms.fbUniforms!;
    const settings = this.game.activeScene.settings;

    uniforms.setUniform("u_ambientLight", settings.ambientLight._raw);
    tempArr4[0] = settings.fogMode;
    tempArr4[1] = settings.fogStart;
    tempArr4[2] = settings.fogStart + settings.fogRange;
    tempArr4[3] = settings.fogDensity;
    uniforms.setUniform("u_fogInfos", tempArr4);
    uniforms.setUniform("u_fogColor", settings.fogColor._raw);
    uniforms.setUniform("u_lightDir", dirL? dirL.direction._raw: [0, 0, 1]);
    uniforms.setUniform("u_lightColor", dirL? dirL.color.scale(dirL.intensity, tempVec3)._raw: [0, 0, 0]);
    tempArr1[0] = this.game.gameTime;
    uniforms.setUniform("u_gameTime", tempArr1);
    tempArr3[0] = settings.subtractiveShadowColor.r / 255.0;
    tempArr3[1] = settings.subtractiveShadowColor.g / 255.0;
    tempArr3[2] = settings.subtractiveShadowColor.b / 255.0;
    uniforms.setUniform("u_shadowColor", tempArr3);
    tempArr1[0] = 1-(dirL? dirL.shadowStrength: 1);
    uniforms.setUniform("u_shadowStrength", tempArr1);
    unifo
点击咨询小助手