flush method

void flush()

Sorts and emits every deferred draw, then finishes recording.

Opaque draws are sorted by pipeline (state-change grouping) and then front-to-back (early-Z), and drawn first. Translucent draws are then sorted back-to-front and drawn with premultiplied source-over blending and depth writes disabled. After this returns the encoder has finished recording into its render pass; the caller submits the owning command buffer.

Implementation

void flush() {
  _opaqueRecords.sort((a, b) {
    final byPipeline = a.pipelineKey.compareTo(b.pipelineKey);
    if (byPipeline != 0) return byPipeline;
    return a.depth.compareTo(b.depth);
  });
  for (final record in _opaqueRecords) {
    final item = record.item;
    final instances = item.instanceTransforms;
    if (instances != null) {
      _encodeInstanced(
        record.pipeline,
        item.worldTransform,
        item.geometry,
        item.material,
        instances,
        item.windingFlipped,
      );
    } else {
      _encode(
        record.pipeline,
        item.worldTransform,
        item.geometry,
        item.material,
        item.windingFlipped,
      );
    }
  }
  _opaqueRecords.clear();

  _translucentRecords.sort((a, b) => b.depth.compareTo(a.depth));
  _renderPass.setDepthWriteEnable(false);
  _renderPass.setColorBlendEnable(true);
  // Premultiplied source-over blending.
  // Note: expects premultiplied-alpha output from the fragment stage.
  _renderPass.setColorBlendEquation(
    gpu.ColorBlendEquation(
      colorBlendOperation: gpu.BlendOperation.add,
      sourceColorBlendFactor: gpu.BlendFactor.one,
      destinationColorBlendFactor: gpu.BlendFactor.oneMinusSourceAlpha,
      alphaBlendOperation: gpu.BlendOperation.add,
      sourceAlphaBlendFactor: gpu.BlendFactor.one,
      destinationAlphaBlendFactor: gpu.BlendFactor.oneMinusSourceAlpha,
    ),
  );
  for (final record in _translucentRecords) {
    _encode(
      record.pipeline,
      record.worldTransform,
      record.geometry,
      record.material,
      record.windingFlipped,
    );
  }
  _translucentRecords.clear();
}