applyShader method
void
applyShader(})
Runs fragmentShader as a full-screen pass that advances this stage's
color chain: the engine binds the current color as sampler2D input_color (sampled at the v_uv varying), renders into the next
buffer, and makes it the current color for downstream passes.
Bind extra inputs with textures (each a sampler2D by name, sampled
with samplers or a default linear-clamp sampler) and uniforms (each
a std140 uniform block by name). Set frameInfo when the shader
declares a PostFrameInfo block (resolution / texel_size / time), the
same contract as a PostEffect.
Call at most once per pass; for multiple chained effects use multiple CustomRenderPasses. At an HDR stage the shader must output linear HDR premultiplied by alpha (the material-shader contract).
Implementation
void applyShader(
gpu.Shader fragmentShader, {
Map<String, gpu.Texture> textures = const {},
Map<String, gpu.SamplerOptions> samplers = const {},
Map<String, ByteData> uniforms = const {},
bool frameInfo = false,
}) {
final input = _context.blackboard.require<gpu.Texture>(_chainKey);
final commandBuffer = gpu.gpuContext.createCommandBuffer();
final renderPass = commandBuffer.createRenderPass(
gpu.RenderTarget.singleColor(gpu.ColorAttachment(texture: _destination)),
);
renderPass.bindPipeline(resolvePipeline(_vertexShader, fragmentShader));
bindVertexBufferCompat(renderPass, _quadView, 6);
renderPass.bindTexture(
fragmentShader.getUniformSlot('input_color'),
input,
sampler: _linearClamp,
);
if (frameInfo) {
final w = dimensions.width;
final h = dimensions.height;
final info = Float32List(8)
..[0] = w
..[1] = h
..[2] = w == 0 ? 0.0 : 1.0 / w
..[3] = h == 0 ? 0.0 : 1.0 / h
..[4] = _time;
renderPass.bindUniform(
fragmentShader.getUniformSlot('PostFrameInfo'),
_context.transientsBuffer.emplace(ByteData.sublistView(info)),
);
}
if (textures.isNotEmpty || uniforms.isNotEmpty) {
final bindings = ShaderUniformBindings();
for (final entry in uniforms.entries) {
bindings.setUniformBlock(entry.key, entry.value);
}
for (final entry in textures.entries) {
bindings.setTexture(
entry.key,
entry.value,
sampler: samplers[entry.key] ?? _linearClamp,
);
}
bindings.bind(renderPass, fragmentShader, _context.transientsBuffer);
}
drawCompat(renderPass, 6);
rendererSubmissions.submit(commandBuffer);
_wrote = true;
}