bind method

  1. @override
void bind(
  1. RenderPass pass,
  2. HostBuffer transientsBuffer,
  3. Matrix4 modelTransform,
  4. Matrix4 cameraTransform,
  5. Vector3 cameraPosition,
)
override

Binds vertex/index buffers and per-frame uniforms onto pass in preparation for a draw call.

Implementations write the model and camera transforms (and any subclass-specific values, like the joints texture for skinned geometry) into the supplied transient buffer and bind the resulting uniform views.

Implementation

@override
void bind(
  gpu.RenderPass pass,
  gpu.HostBuffer transientsBuffer,
  vm.Matrix4 modelTransform,
  vm.Matrix4 cameraTransform,
  vm.Vector3 cameraPosition,
) {
  if (_jointsTexture == null) {
    throw Exception('Joints texture must be set for skinned geometry.');
  }

  pass.bindTexture(
    vertexShader.getUniformSlot('joints_texture'),
    _jointsTexture!,
    sampler: gpu.SamplerOptions(
      minFilter: gpu.MinMagFilter.nearest,
      magFilter: gpu.MinMagFilter.nearest,
      mipFilter: gpu.MipFilter.nearest,
      widthAddressMode: gpu.SamplerAddressMode.clampToEdge,
      heightAddressMode: gpu.SamplerAddressMode.clampToEdge,
    ),
  );

  if (_vertices == null) {
    throw Exception(
      'SetVertices must be called before GetBufferView for Geometry.',
    );
  }

  pass.bindVertexBuffer(_vertices!, _vertexCount);
  if (_indices != null) {
    pass.bindIndexBuffer(_indices!, _indexType, _indexCount);
  }

  // Skinned vertex UBO. The model transform is identity on purpose:
  // the joint matrices from Skin.getJointsTexture are already full
  // global transforms (including the scene-root flip), so the shader
  // applies them directly. Passing the mesh node's own transform here
  // would double-apply it (and glTF requires a skinned mesh node's
  // transform to be ignored). `modelTransform` is unused for skinned
  // geometry as a result.
  final identityTransform = vm.Matrix4.identity();
  final frameInfoSlot = vertexShader.getUniformSlot('FrameInfo');
  final frameInfoFloats = Float32List.fromList([
    identityTransform.storage[0],
    identityTransform.storage[1],
    identityTransform.storage[2],
    identityTransform.storage[3],
    identityTransform.storage[4],
    identityTransform.storage[5],
    identityTransform.storage[6],
    identityTransform.storage[7],
    identityTransform.storage[8],
    identityTransform.storage[9],
    identityTransform.storage[10],
    identityTransform.storage[11],
    identityTransform.storage[12],
    identityTransform.storage[13],
    identityTransform.storage[14],
    identityTransform.storage[15],
    cameraTransform.storage[0],
    cameraTransform.storage[1],
    cameraTransform.storage[2],
    cameraTransform.storage[3],
    cameraTransform.storage[4],
    cameraTransform.storage[5],
    cameraTransform.storage[6],
    cameraTransform.storage[7],
    cameraTransform.storage[8],
    cameraTransform.storage[9],
    cameraTransform.storage[10],
    cameraTransform.storage[11],
    cameraTransform.storage[12],
    cameraTransform.storage[13],
    cameraTransform.storage[14],
    cameraTransform.storage[15],
    cameraPosition.x,
    cameraPosition.y,
    cameraPosition.z,
    _jointsTexture != null ? 1 : 0,
    _jointsTexture != null ? _jointsTextureWidth.toDouble() : 1.0,
  ]);
  final frameInfoView = transientsBuffer.emplace(
    frameInfoFloats.buffer.asByteData(),
  );
  pass.bindUniform(frameInfoSlot, frameInfoView);
}