谷主
Webgl版本可以魔改一下,但是,其它后端不行,以下是我问AI的回答。这个对我来说比较关键,我觉得至少要先开放相关接口,至少能先在webgl侧由用户自己实现。
跨后端的边界在哪里
整个渲染驱动是三层结构:
资源层 / 命令层(RenderTexture、CommandBuffer、SetRTCMD)——完全开源、后端无关。
契约层(DriverDesign 下的 ITextureContext、InternalRenderTarget、InternalTexture)——开源,但它是所有后端的统一接口。
驱动实现层——WebGL 全开源;GLES / LayaX 只是薄薄一层 TS 绑定,真正的实现在闭源 C++(conch 原生对象)里。
关键证据,看 native 的 TextureContext 和 InternalRT:
GLESTextureContext.ts:135-137(LayaX 版 LayaXTextureContext.ts:132-134 完全同构):
createRenderTargetInternal(width, height, colorFormat, depthStencilFormat, ...) {
return new GLESInternalRT(
this._native.createRenderTargetInternal(width, height, colorFormat, ...) // 单个 colorFormat 标量
);
}
GLESInternalRT.ts:85-97:
get textures(): InternalTexture[] {
this.texturesRef = [];
let textures = this.nativeObj.getTextures(); // 纹理列表是 C++ 建的,TS 只是读回来
textures.forEach(e => this.texturesRef.push(new GLESInternalTex(e)));
...
}
这说明了三点:
FBO 的组装、颜色纹理的创建、getTextures()、bindRenderTarget 里的 drawBuffers,全在闭源 C++ 里。 TS 侧只是读回结果。
textures 数组的"伏笔"在这里是假象:native 的 createRenderTargetInternal 只接收单个 colorFormat 标量,所以 getTextures() 永远只吐一张颜色纹理。TS 层既不能往里塞第二张,也没法让 native 多建一张。
契约层 InternalRenderTarget.textures 是 InternalTexture[] 数组,只代表"能读 N 张",不代表"能创建 N 个附件"——创建是 native 独占的。
所以,深度改造的影响是分层的
改动位置 开源? 改 MRT 的可行性
资源层 RenderTexture / 新增类 ✅ 可改,但只够改语义,够不着 native
CommandBuffer / SetRTCMD ✅ 可改,但它是"重绑"层,不是 MRT 层
WebGL 驱动 GL/GL2TextureContext ✅ 可改,drawBuffers 已就位
ITextureContext 契约 + native FFI ❌ 闭源 改不动
结论:只要你想让 MRT 在所有后端都跑通,就必然要动 ITextureContext(比如新增 createMRTRenderTargetInternal,或让 createRenderTargetInternal 接受颜色格式数组)。而这一步 native 的 C++ 不配合,TS 加了接口也只是运行时 undefined 调用崩溃。这就是"有限改造"的硬边界。
有限改造下的可行路线
路线 A(推荐,契约零改动):WebGL 独占 MRT + native 降级
只在 WebGL 驱动里实现多附件(GL2TextureContext.createRenderTargetInternal 支持颜色格式数组 + drawBuffers,这部分全开源)。
用能力检测(WebGL2 / native)区分:native 走多次单附件 pass(把每个 MRT 目标拆成独立的 RenderTexture,多 pass 各渲一遍),结果正确、只是少了单 pass 性能收益。
完全不碰 ITextureContext 契约,native 代码一行不用改。
路线 B:真要让 native 单 pass MRT
必须由 native(闭源)团队在 C++ 侧加一个 FFI(例如 createRenderTargetInternal 支持 colorFormat[] + 绑定时的 glDrawBuffers/glFramebufferTexture2D(COLOR_ATTACHMENT0+i)),TS 侧再补对应绑定。这超出本仓库可改范围,属于跨团队协作。
一句话:MRT 的创建端在闭源 native,setRenderTarget 这类开源层改再深也到不了那一端;能安全做的只有 WebGL 侧真 MRT + native 多 pass 降级,或者推动 native 团队开一个新 FFI。