【发布时间】:2019-10-11 03:33:02
【问题描述】:
为了实现一些后期处理效果,我想将场景渲染成纹理,而不是直接渲染到屏幕上。出于测试目的,我在一个横跨整个屏幕的简单四边形上绘制了这个纹理。但图像质量令人失望:
将场景渲染到屏幕
VS
将场景渲染到纹理
我真的不知道,为什么会这样。画布大小适合绘图缓冲区大小。此外,在调整屏幕大小时,我会创建一个全新的纹理、帧和渲染缓冲区。我的帧缓冲区设置不正确吗?还是 WebGL 的限制?我正在使用 Google Chrome 和 WebGL2。
function resize() {
if (tex) { tex.delete(); }
if (fb) { gl.deleteFramebuffer(fb); }
if (rb) { gl.deleteRenderbuffer(rb); }
fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
tex = new Texture2D(null, {
internalFormat: gl.RGB,
width: gl.drawingBufferWidth,
height: gl.drawingBufferHeight,
minFilter: gl.LINEAR,
magFilger: gl.LINEAR
});
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex.id, 0);
rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rb);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
run() {
gl.resize();
gl.addEventListener('resize', resize);
resize();
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.loop(() => {
if (!ctx.scene || !ctx.car || !ctx.wheels) return;
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
renderScene();
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
screenShader.use();
screen.bind();
screenShader.screenMap = tex.active(0);
gl.drawElements(gl.TRIANGLES, screen.length, gl.UNSIGNED_SHORT, 0);
});
}
【问题讨论】:
-
尝试关闭画布上的抗锯齿,看看画布质量是否下降到纹理质量。
gl = canvas.getContext("webgl2", { antialias: false }) -
您确定您的纹理与您的屏幕具有相同的分辨率吗?我不在 WEBGL 中编写代码,但在 GL 中,纹理大小受到限制,并且某些实现的纹理大小低于屏幕分辨率......图像看起来像调整大小的纹理大小是否与您的视图大小完全匹配(您知道窗口也有边框所以窗口大小与视图大小不同)?使用的纹理坐标也是如此,您使用了
GL_CLAMP_TO_EDGE吗?还是通过0.5texel 调整纹理坐标? -
屏幕限制和纹理限制是一样的,不需要调整半个像素
-
@gman 是的,你是对的。关闭抗锯齿后,质量下降到相同的纹理质量......这是否意味着,我无能为力?将纹理调整为双屏幕宽度和高度会产生良好的渲染结果,但性能会受到太大影响。你知道如何解决这个问题吗?
标签: glsl render-to-texture webgl2 image-quality