bind method

  1. @override
void bind(
  1. RenderPass pass,
  2. TransientWriter transientsBuffer,
  3. Lighting lighting
)
override

Binds this material's render-pass state, uniforms, and textures.

The base implementation enables back-face culling with counter-clockwise winding (matching the glTF convention). Subclasses must call super.bind and then bind any per-material uniforms and textures expected by their fragment shader. lighting carries the IBL EnvironmentMap (and its intensity) plus the analytic lights and shadow resources that materials shade against.

Implementation

@override
void bind(
  gpu.RenderPass pass,
  TransientWriter transientsBuffer,
  Lighting lighting,
) {
  super.bind(pass, transientsBuffer, lighting);
  // A camera-facing quad's winding flips with the viewing angle, so cull
  // nothing rather than guess a front face.
  pass.setCullMode(gpu.CullMode.none);
  // Sprites keep the encoder's translucent depth state: the lessEqual test
  // (so opaque geometry occludes them) with depth writes off (so the
  // overlapping instances of one instanced draw do not self-occlude).

  final viewport = lighting.viewportSize;
  final depthAvailable = lighting.sceneDepthLinear != null;
  final fragInfo = Float32List(12);
  fragInfo[0] = tint.r;
  fragInfo[1] = tint.g;
  fragInfo[2] = tint.b;
  fragInfo[3] = tint.a;
  fragInfo[4] = blendMode == SpriteBlendMode.additive ? 1.0 : 0.0;
  fragInfo[5] = depthAvailable && softDepthFade > 0.0
      ? 1.0 / softDepthFade
      : 0.0;
  fragInfo[6] = cameraNearFade > 0.0 ? 1.0 / cameraNearFade : 0.0;
  fragInfo[8] = viewport.width > 0 ? 1.0 / viewport.width : 0.0;
  fragInfo[9] = viewport.height > 0 ? 1.0 / viewport.height : 0.0;
  pass.bindUniform(
    fragmentShader.getUniformSlot('FragInfo'),
    transientsBuffer.emplace(ByteData.sublistView(fragInfo)),
  );
  pass.bindTexture(
    fragmentShader.getUniformSlot('base_color_texture'),
    Material.whitePlaceholder(resolveTextureSource(colorTexture)),
    sampler: textureSourceSampler(colorTexture) ?? sampler,
  );
  // Always bound (a white placeholder when the prepass did not run) so the
  // sampler is never left dangling; the fade is disabled in that case.
  EngineLightingUniforms.bindSceneInputTextures(
    pass,
    fragmentShader,
    lighting,
    const {RenderInput.depth},
  );
}