createPass()
创建一个冻结的 Pipeline Pass Definition。
签名
function createPass<T>(
name: string,
setup: (context: PassContext) => T,
options?: {
enabled?: boolean;
order?: number;
stage?: 'after-render' | 'after-output';
},
): PassDefinition<T>;用法
const nativePass = new ShaderPass(MyShader);
const Effect = createPass('effect', ({
onDestroy,
onPrepareFrame,
onResize,
usePass,
}) => {
usePass(nativePass); // 默认进入后处理链
onPrepareFrame(({ delta, elapsed, renderer, size, views }) => {
updateEffect(nativePass, elapsed);
});
onResize(({ width, height, pixelRatio }) => {
updateResolution(nativePass, width * pixelRatio, height * pixelRatio);
});
onDestroy(() => nativePass.dispose());
return nativePass;
}, {
stage: 'after-render',
order: 10,
enabled: false,
});
engine.pipeline.addPass(Effect);
engine.pipeline.setPassEnabled(Effect, true);usePass 只在 setup 可调用。Pipeline 借用原生 Pass、负责排序、setSize 与执行,但不 dispose;资源由创建它的业务 owner 释放。
usePass(pass, { present: true }) 声明 manual 模式的最终上屏 Pass;usePass(pass, { target: 'canvas' }) 声明颜色输出完成后直接绘制默认 framebuffer。两种 contribution 仍使用同一个 API。
Canvas contribution 是只写的 direct-draw lane。Pipeline 会把 renderer 恢复到默认 framebuffer baseline,并以 renderToScreen = true 调用 Pass;传给 Pass.render() 的 writeBuffer / readBuffer 仅用于兼容 Three.js 方法签名,不承诺稳定的画面内容或颜色空间,业务不得采样或依赖。需要读取整张画面的 Pass 应使用 Composer target:读取输出变换前的 working-space 内容时放在 after-render,读取输出变换后的 output-encoded 内容时使用 after-output + manual 模式。
after-output 的 Composer contribution 只在 manual 模式执行;auto 模式会跳过它,但仍执行该阶段的 Canvas contribution。addPass() / hasPass() / isPassEnabled() 描述 owner 的安装与 enabled 状态,不表示其 contribution 在当前 output mode 下必然进入本帧计划。业务应把相关 owner 开关与 setOutputMode() 封装成一次领域操作。
manual 模式存在有效颜色工作但缺少最终 present: true contribution 时,Pipeline 不会 fallback 或清屏,并会在每个连续异常周期输出一次 console.warn。Canvas contribution 不能替代最终颜色 presenter。
Pipeline 的 main 与 OutputPass 固定由 Engine 持有,业务不能替换。