init method

dynamic init(
  1. dynamic cacheKey,
  2. WebGPUProgrammableStage stageVertex,
  3. WebGPUProgrammableStage stageFragment,
  4. dynamic object,
  5. dynamic nodeBuilder,
)

Implementation

init(cacheKey, WebGPUProgrammableStage stageVertex,
    WebGPUProgrammableStage stageFragment, object, nodeBuilder) {
  var material = object.material;
  var geometry = object.geometry;

  // determine shader attributes

  var shaderAttributes = this._getShaderAttributes(nodeBuilder, geometry);

  // vertex buffers

  List<GPUVertexBufferLayout> vertexBuffers = [];

  for (var attribute in shaderAttributes) {
    var name = attribute["name"];
    var geometryAttribute = geometry.getAttribute(name);
    var stepMode = (geometryAttribute != undefined &&
            geometryAttribute is InstancedBufferAttribute)
        ? GPUInputStepMode.Instance
        : GPUInputStepMode.Vertex;

    vertexBuffers.add(GPUVertexBufferLayout(
        arrayStride: attribute["arrayStride"],
        attributes: [
          GPUVertexAttribute(
              shaderLocation: attribute["slot"],
              offset: 0,
              format: attribute["format"])
        ],
        stepMode: stepMode));
  }

  this.cacheKey = cacheKey;
  this.shaderAttributes = shaderAttributes;
  this.stageVertex = stageVertex;
  this.stageFragment = stageFragment;

  // blending

  var alphaBlend = {};
  var colorBlend = {};

  if (material.transparent == true && material.blending != NoBlending) {
    alphaBlend = this._getAlphaBlend(material);
    colorBlend = this._getColorBlend(material);
  }

  // stencil

  var stencilFront = {};

  if (material.stencilWrite == true) {
    stencilFront = {
      "compare": this._getStencilCompare(material),
      "failOp": this._getStencilOperation(material.stencilFail),
      "depthFailOp": this._getStencilOperation(material.stencilZFail),
      "passOp": this._getStencilOperation(material.stencilZPass)
    };
  }

  var primitiveState = this._getPrimitiveState(object, material);
  var colorWriteMask = this._getColorWriteMask(material);
  var depthCompare = this._getDepthCompare(material);
  var colorFormat = this._renderer.getCurrentColorFormat();
  var depthStencilFormat = this._renderer.getCurrentDepthStencilFormat();

  var _vertexState = GPUVertexState(
      module: stageVertex.stage["module"],
      entryPoint: stageVertex.stage["entryPoint"],
      buffers: vertexBuffers);
  var _fragmentState = GPUFragmentState(
      entryPoint: stageFragment.stage["entryPoint"],
      module: stageFragment.stage["module"],
      targets: GPUColorTargetState(
          blend: GPUBlendState(
              alpha: GPUBlendComponent(
                srcFactor: alphaBlend["srcFactor"],
                dstFactor: alphaBlend["dstFactor"],
                operation: alphaBlend["operation"],
              ),
              color: GPUBlendComponent(
                srcFactor: alphaBlend["srcFactor"],
                dstFactor: alphaBlend["dstFactor"],
                operation: alphaBlend["operation"],
              )),
          format: colorFormat,
          writeMask: colorWriteMask));
  var _depthStencilState = GPUDepthStencilState(
    format: depthStencilFormat,
    depthWriteEnabled: material.depthWrite,
    depthCompare: depthCompare,
    stencilFront: GPUStencilFaceState(compare: stencilFront['compare']),
    // stencilBack: {}, // three.js does not provide an API to configure the back function (gl.stencilFuncSeparate() was never used)
    // stencilBack: GPUStencilFaceState(
    //   compare: GPUCompareFunction.Never
    // ),
    // stencilReadMask: material.stencilFuncMask,
    // stencilWriteMask: material.stencilWriteMask
  );

  bindGroupLayout = this
      ._device
      .createBindGroupLayout(GPUBindGroupLayoutDescriptor(entries: [
        GPUBindGroupLayoutEntry(
          binding: 0,
          visibility: GPUShaderStage.Vertex,
          buffer: GPUBufferBindingLayout(
            type: GPUBufferBindingType.Uniform
          )
        ),
        GPUBindGroupLayoutEntry(
            binding: 1,
            visibility: GPUShaderStage.Fragment,
            buffer: GPUBufferBindingLayout(type: GPUBufferBindingType.Uniform))
      ]));

  var pipelineLayout = this._device.createPipelineLayout(
      GPUPipelineLayoutDescriptor(
          bindGroupLayouts: bindGroupLayout, bindGroupLayoutCount: 1));

  var _renderPipelineDescriptor = GPURenderPipelineDescriptor(
      layout: pipelineLayout,
      vertex: _vertexState,
      fragment: _fragmentState,
      primitive: primitiveState,
      depthStencil: _depthStencilState,
      multisample: GPUMultisampleState(count: this._sampleCount)
    );

  print(" GPURenderPipelineDescriptor _sampleCount: ${_sampleCount} ");

  this.pipeline =
      this._device.createRenderPipeline(_renderPipelineDescriptor);
}