繁体   English   中英

是否可以在WebGL2中将MSAA渲染为RGBA32F纹理?

[英]Is it possible to render MSAA to RGBA32F texture in WebGL2?

首先,我的msaa运作良好,就像这样(抽象):

    sceneFramebuffer = new MultisampleRenderbuffer({
        msaa: 8,
        internalFormat: "RGBA8"
    });

    blitFramebuffer = new Framebuffer({
        internalFormat: "RGBA8",
        format: "RGBA",
        type: "UNSIGNED_INT"
    });

   Draw scene with sceneFramebuffer;

   sceneFramebuffer.blit(blitFramebuffer);

   Draw blitFramebuffer on the screen quad;

现在,我想将sceneFramebuffer渲染为用于HDR的RGBA32F,并且在尝试这种配置时:

sceneFramebuffer = new MultisampleRenderbuffer({
    msaa: 8
    internalFormat: "RGBA32F"
});

blitFramebuffer = new Framebuffer({
    internalFormat: "RGBA32F",
    format: "RGBA",
    type: "FLOAT"
});

我得到这个:GL错误:GL_INVALID_OPERATION:glBlitFramebufferCHROMIUM:src和dst格式的颜色不同

但是,当我为sceneFramebuffer设置msaa:0时 ,它显示了我的场景,但没有msaa的课程平滑处理。

是否可以以某种方式将多重采样和浮点输出结合在一起,而我将其用于hdr?

谢谢!

似乎为我工作

 function main() { const gl = document.querySelector('canvas').getContext('webgl2'); if (!gl) { return alert('need webgl2'); } // without this we can't render to RGBA32F if (!gl.getExtension('EXT_color_buffer_float')) { return alert('need EXT_color_buffer_float'); } // just guessing without this we can't downsample if (!gl.getExtension('OES_texture_float_linear')) { return alert('need OES_texture_float_linear'); } const msFB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, msFB); const msRB = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, msRB); const samples = 4; const internalFormat = gl.RGBA32F; const width = 16; const height = 16; gl.renderbufferStorageMultisample( gl.RENDERBUFFER, samples, internalFormat, width, height); gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msRB); checkFramebuffer(gl); gl.clearColor(1,0,0,1); gl.clear(gl.COLOR_BUFFER_BIT); const texFB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, texFB); const tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex); const levels = 1; gl.texStorage2D(gl.TEXTURE_2D, levels, internalFormat, width, height); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); checkFramebuffer(gl); // check before checkPixel(gl, 'before blit') gl.bindFramebuffer(gl.READ_FRAMEBUFFER, msFB); gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, texFB); gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.LINEAR); console.log('ERROR?:', glEnumToString(gl, gl.getError())); gl.bindFramebuffer(gl.FRAMEBUFFER, texFB); checkPixel(gl, 'after blit:'); } function checkFramebuffer(gl) { const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); if (status !== gl.FRAMEBUFFER_COMPLETE) { console.error(glEnumToString(gl, status)); } } function checkPixel(gl, msg) { const pixel = new Float32Array(4); gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, pixel); console.log(msg, Array.from(pixel).join(', ')); } function glEnumToString(gl, v) { const hits = []; for (const key in gl) { if (gl[key] === v) { hits.push(key); } } return hits.length ? hits.join(' | ') : `0x${v.toString(16)}`; } main(); 
 <canvas></canvas> 

为了清楚起见,它与texStorage2D无关

 function main() { const gl = document.querySelector('canvas').getContext('webgl2'); if (!gl) { return alert('need webgl2'); } // without this we can't render to RGBA32F if (!gl.getExtension('EXT_color_buffer_float')) { return alert('need EXT_color_buffer_float'); } // just guessing without this we can't downsample if (!gl.getExtension('OES_texture_float_linear')) { return alert('need OES_texture_float_linear'); } const msFB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, msFB); const msRB = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, msRB); const samples = 4; const internalFormat = gl.RGBA32F; const width = 16; const height = 16; gl.renderbufferStorageMultisample( gl.RENDERBUFFER, samples, internalFormat, width, height); gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msRB); checkFramebuffer(gl); gl.clearColor(1,0,0,1); gl.clear(gl.COLOR_BUFFER_BIT); const texFB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, texFB); const tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex); const level = 0; gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, width, height, 0, gl.RGBA, gl.FLOAT, null); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); checkFramebuffer(gl); // check before checkPixel(gl, 'before blit') gl.bindFramebuffer(gl.READ_FRAMEBUFFER, msFB); gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, texFB); gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.LINEAR); console.log('ERROR?:', glEnumToString(gl, gl.getError())); gl.bindFramebuffer(gl.FRAMEBUFFER, texFB); checkPixel(gl, 'after blit:'); } function checkFramebuffer(gl) { const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); if (status !== gl.FRAMEBUFFER_COMPLETE) { console.error(glEnumToString(gl, status)); } } function checkPixel(gl, msg) { const pixel = new Float32Array(4); gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, pixel); console.log(msg, Array.from(pixel).join(', ')); } function glEnumToString(gl, v) { const hits = []; for (const key in gl) { if (gl[key] === v) { hits.push(key); } } return hits.length ? hits.join(' | ') : `0x${v.toString(16)}`; } main(); 
 <canvas></canvas> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM